我有一个这样定义的枚举:
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和字符串,并将对象构建为数组?
我不建议在需要枚举条目列表的情况下使用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。钥匙等,以安全一致的方式。
你可以这样做:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
export class GoalProgressMeasurement {
constructor(public goalProgressMeasurement: GoalProgressMeasurements, public name: string) {
}
}
export var goalProgressMeasurements: { [key: number]: GoalProgressMeasurement } = {
1: new GoalProgressMeasurement(GoalProgressMeasurements.Percentage, "Percentage"),
2: new GoalProgressMeasurement(GoalProgressMeasurements.Numeric_Target, "Numeric Target"),
3: new GoalProgressMeasurement(GoalProgressMeasurements.Completed_Tasks, "Completed Tasks"),
4: new GoalProgressMeasurement(GoalProgressMeasurements.Average_Milestone_Progress, "Average Milestone Progress"),
5: new GoalProgressMeasurement(GoalProgressMeasurements.Not_Measured, "Not Measured"),
}
你可以这样使用它:
var gpm: GoalProgressMeasurement = goalProgressMeasurements[GoalProgressMeasurements.Percentage];
var gpmName: string = gpm.name;
var myProgressId: number = 1; // the value can come out of drop down selected value or from back-end , so you can imagine the way of using
var gpm2: GoalProgressMeasurement = goalProgressMeasurements[myProgressId];
var gpmName: string = gpm.name;
您可以根据需要使用对象的附加属性扩展GoalProgressMeasurement。我将这种方法用于每个应该是包含多个值的对象的枚举。
我不喜欢上面的答案,因为它们都不能正确地处理字符串/数字的混合,可以在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上的值。