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

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和字符串,并将对象构建为数组?


当前回答

我是这样解的

        const listKeys = Object.keys(TripStatus); //TripStatus is enum type
        const numOfItem = listKeys.length/2;
        for(let i=0; i<numOfItem; i++){
          this.listStatus.push({
            id: listKeys[i],
            name: listKeys[numOfItem+i]
          })
        }

其他回答

首先,我们得到这个枚举的键数组。然后,使用map()函数将数据转换为所需的格式。Id从键获取,name从enum通过相同的键获取。

const converted = Object.keys(GoalProgressMeasurements).map(key => {
        return {
            id: GoalProgressMeasurements[key],
            name: key,
        };
    });

我使用

Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));

一条简单的线就可以做到这一点。

它只需要3个简单的步骤 -使用Object.entries加载键和值的组合。 -过滤掉非数字(因为typescript会为反向查找生成值)。 -然后我们将它映射到我们喜欢的数组对象。

我不喜欢上面的答案,因为它们都不能正确地处理字符串/数字的混合,可以在TypeScript enum中作为值。

下面的函数遵循TypeScript枚举的语义,给出键到值的正确映射。从那里,获取一个对象数组或者仅仅是键或者仅仅是值是很简单的。

/**
 * Converts the given enum to a map of the keys to the values.
 * @param enumeration The enum to convert to a map.
 */
function enumToMap(enumeration: any): Map<string, string | number> {
  const map = new Map<string, string | number>();
  for (let key in enumeration) {
      //TypeScript does not allow enum keys to be numeric
      if (!isNaN(Number(key))) continue;

      const val = enumeration[key] as string | number;

      //TypeScript does not allow enum value to be null or undefined
      if (val !== undefined && val !== null)
          map.set(key, val);
  }

  return map;
}

使用示例:

enum Dog {
    Rover = 1,
    Lassie = "Collie",
    Fido = 3,
    Cody = "Mutt",
}

let map = enumToMap(Dog); //Map of keys to values

let objs = Array.from(map.entries()).map(m => ({id: m[1], name: m[0]})); //Objects as asked for in OP
let entries = Array.from(map.entries()); //Array of each entry
let keys = Array.from(map.keys()); //An array of keys
let values = Array.from(map.values()); //An array of values

我还要指出OP是逆向思考枚举的。枚举中的“键”在技术上是在左边,而值在右边。TypeScript允许你尽可能多地重复RHS上的值。

 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 enum。

在运行时,Enum是作为对象实现的,但它只在这种情况下工作:

enum X {
  Z = 'z',
  F = 'f'
};

console.log(Object.values(X))
console.log(Object.keys(X))
>>>
[LOG]: ["z", "f"] 
[LOG]: ["Z", "F"] 

在这种情况下,它与陷阱一起工作(TS让你通过它的数值访问值):

enum X {
  Z,
  F
};

console.log(Object.values(X))
console.log(Object.keys(X))
>>>
[LOG]: ["Z", "F", 0, 1] 
[LOG]: ["0", "1", "Z", "F"] 

因此,根据Enum定义,任何你写在Enum上循环的函数都将工作/失败。这是…不好的。

我的结论是:Enum不是被设计用来作为对象的。如果你需要访问键和值集合,请使用const而不是enum:

const Enumed = {
    X: 1,
    Y: 2
}

Typescript将控制对象键的存在,你将能够使用object。钥匙等,以安全一致的方式。