Thanks to polkovnikov.ph I was finally able to find a solution that would work for most of the use-cases.
Valid solution for the question
type Descripted<T> = { [K in keyof T]: { readonly id: T[K]; readonly description: string; } }[keyof T] /** * Helper to produce an array of enum descriptors. * @param enumeration Enumeration object. * @param separatorRegex Regex that would catch the separator in your enum key. */ export function enumToDescriptedArray<T>(enumeration: T, separatorRegex: RegExp = /_/g): Descripted<T>[] { return (Object.keys(enumeration) as Array<keyof T>) .filter(key => isNaN(Number(key))) .filter(key => typeof enumeration[key] === "number" || typeof enumeration[key] === "string") .map(key => ({ id: enumeration[key], description: String(key).replace(separatorRegex, ' '), })); }
Example:
export enum GoalProgressMeasurements { Percentage = 1, Numeric_Target = 2, Completed_Tasks = 3, Average_Milestone_Progress = 4, Not_Measured = 5 } console.log(enumToDescriptedArray(GoalProgressMeasurements)) // Produces: /* [ {id: 1, description: "Percentage"}, {id: 2, description: "Numeric Target"}, {id: 3, description: "Completed Tasks"}, {id: 4, description: "Average Milestone Progress"}, {id: 5, description: "Not Measured"} ] */
Also, there's a useful util function I use to map the enumeration object to an array of available values it has:
The mapper
type NonFunctional<T> = T extends Function ? never : T; /** * Helper to produce an array of enum values. * @param enumeration Enumeration object. */ export function enumToArray<T>(enumeration: T): NonFunctional<T[keyof T]>[] { return Object.keys(enumeration) .filter(key => isNaN(Number(key))) .map(key => enumeration[key]) .filter(val => typeof val === "number" || typeof val === "string"); }
Working use-cases
enum Colors1 { WHITE = 0, BLACK = 1 } console.log(Object.values(Colors1)); // ['WHITE', 'BLACK', 0, 1] console.log(enumToArray(Colors1)); // [0, 1]
enum Colors2 { WHITE = "white", BLACK = "black" } console.log(Object.values(Colors2)); // ['white', 'black'] console.log(enumToArray(Colors2)); // ['white', 'black']
enum Colors4 { WHITE = "white", BLACK = 0 } console.log(Object.values(Colors4)); // ["BLACK", "white", 0] console.log(enumToArray(Colors4)); // ["white", 0]
- Enum merged with a namespace with exported functions
enum Colors3 { WHITE = "white", BLACK = "black" } namespace Colors3 { export function fun() {} } console.log(Object.values(Colors3)); // ['white', 'black', Function] console.log(enumToArray(Colors3)); // ['white', 'black']
GoalProgressMeasurements[GoalProgressMeasurements.Completed_Tasks]to get the enum name. I do not know if that helps.