我有一个这样定义的枚举:

export enum GoalProgressMeasurements {
    Percentage = 1,
    Numeric_Target = 2,
    Completed_Tasks = 3,
    Average_Milestone_Progress = 4,
    Not_Measured = 5
}

然而,我希望它被表示为一个对象数组/列表从我们的API如下:

[{id: 1, name: 'Percentage'}, 
 {id: 2, name: 'Numeric Target'},
 {id: 3, name: 'Completed Tasks'},
 {id: 4, name: 'Average Milestone Progress'},
 {id: 5, name: 'Not Measured'}]

是否有简单和本地的方法来做到这一点,或者我必须构建一个函数,将枚举转换为int和字符串,并将对象构建为数组?


当前回答

多亏了波尔科夫尼科夫。我终于能够找到一个解决方案,将工作的大多数用例。

问题的有效解

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, ' '),
        }));
}

例子:


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"}
]
*/

此外,我还使用了一个有用的util函数来将枚举对象映射到它拥有的可用值数组:

该映射器

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");
}

用例工作

数字枚举

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


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']

其他回答

枚举是运行时存在的真实对象。所以你可以这样反向映射:

let value = GoalProgressMeasurements.Not_Measured;
console.log(GoalProgressMeasurements[value]);
// => Not_Measured

基于此,您可以使用以下代码:

export enum GoalProgressMeasurements {
    Percentage = 1,
    Numeric_Target = 2,
    Completed_Tasks = 3,
    Average_Milestone_Progress = 4,
    Not_Measured = 5
}

let map: {id: number; name: string}[] = [];

for(var n in GoalProgressMeasurements) {
    if (typeof GoalProgressMeasurements[n] === 'number') {
        map.push({id: <any>GoalProgressMeasurements[n], name: n});
    }
}

console.log(map);

参考:https://www.typescriptlang.org/docs/handbook/enums.html

有一个简单的解决方案,当你运行object。Keys (Enum)它会给你一个值和键的数组,在第一个slice Values中,在第二个slice key中,为什么我们不直接返回第二个slice,下面的代码对我来说是有用的。

enum Enum {
   ONE,
   TWO,
   THREE,
   FOUR,
   FIVE,
   SIX,
   SEVEN
}
const keys = Object.keys(Enum); 
console.log(keys.slice(keys.length / 2));

在数组中获取enum值。

export enum DocumentationTypeEnum {
  GDPR = 'GDPR',
  HELP = 'HELP',
  OTHER = 'OTHER',
  FOOTER = 'FOOTER'
}
const keys = Object.keys(DocumentationTypeEnum);
    
console.log(keys); // Output :  ["GDPR", "HELP", "OTHER", "FOOTER"]
 this worked for me :

    export enum FeedBackType {
    FEEDBACK1= 'FEEDBACK1',
    FEEDBACK2= 'FEEDBACK2',
    FEEDBACK3= 'FEEDBACK3',
    }

----------------------------------------------------------------- 
    export function getTypeFeedBackList() {
    let feedbackList: FeedBackType[] = [];
    Object.keys(FeedBackType).map((key) => {
    let strEnum = key as unknown as FeedBackType;
    feedbackList.push(strEnum);
    });
    return feedbackList;
    }
---------------------------------------------------------------- 
declare this :

    public feedbackList: FeedBackType[] = [];

and after call your function in  :

    ngOnInit(): void {
    this.feedbackList = getTypeFeedBackList();
    console.log(this.feedbackList); 
    }

Happy coding ;) 

TS:

仅适用于短(<10个元素)enum

const keys = Object.keys(Enum).filter((el: string) => el.length > 1)
console.log(keys)

Object.keys()将返回一个包含['0','1','2','enumElement1', 'enumElement2', enumElement3']的数组 Filter()获取每个元素并检查其长度(因为字符串),并从结果数组中排除所有数字