With the guidance of polkovnikov.ph, I was able to uncover a solution that caters to most use-cases.
Solution Approved for the Query
type Described<T> = {
[K in keyof T]: {
readonly id: T[K];
readonly description: string;
}
}[keyof T]
/**
* Utility to generate an array of enum descriptors.
* @param enumeration The Enum object.
* @param separatorRegex Regex pattern identifying key separators in your enum.
*/
export function enumToDescribedArray<T>(enumeration: T, separatorRegex: RegExp = /_/g): Described<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, ' '),
}));
}
For instance:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
console.log(enumToDescribedArray(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"}
]
*/
Additionally, there's a convenient utility function I employ to map the enum object to an array of its available values:
The Mapper
type NonFunctional<T> = T extends Function ? never : T;
/**
* Utility to create an array of enum values.
* @param enumeration The Enum 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");
}
Successful 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 Featuring 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']