type InputValues = Record | Array<[K, V]>; /** * Handles mapping enums to arbitrary values. */ export class EnumMapper { private map: Map; private fallback: V; constructor(values: InputValues, fallback: V) { const entries = Array.isArray(values) ? values : ( (Object.entries(values) as Array<[K, V]>) ); this.map = new Map(entries); this.fallback = fallback; } /** * Returns a value corresponding to the provided key. * * If no match is found, returns the fallback value provided in the constructor. * * Note that TypeScript will make sure that we only ever use the right types * as the enum param, but it can still happen at runtime that different * values are provided. */ get(key: K | undefined): V { if (key === undefined) { return this.fallback; } const value = this.map.get(key); if (value === undefined) { return this.fallback; } return value; } /** * All enums known by this mapper. */ get enums() { return Array.from(this.map.keys()); } /** * Checks whether key is known by the mapper. */ has(value: string | number): value is K { return this.map.has(value as K); } static from(values: InputValues) { return new EnumMapper(values, "Unknown"); } }