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. – Zoophyte