我有一个这样定义的枚举:
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和字符串,并将对象构建为数组?
我不认为顺序是可以保证的,否则就很容易切片Object的后半部分。条目的结果和映射来自那里。
上述答案的唯一(非常小的)问题是
字符串和数字之间有很多不必要的类型转换。
当一次迭代同样干净有效时,条目将迭代两次。
type StandardEnum = { [id: string]: number | string; [nu: number]: string;}
function enumToList<T extends StandardEnum> (enm: T) : { id: number; description: string }[] {
return Object.entries(enm).reduce((accum, kv) => {
if (typeof kv[1] === 'number') {
accum.push({ id: kv[1], description: kv[0] })
}
return accum
}, []) // if enum is huge, perhaps pre-allocate with new Array(entries.length / 2), however then push won't work, so tracking an index would also be required
}
我不建议在需要枚举条目列表的情况下使用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 UnitEnum {
GRAM = 'gm',
KILOGRAM = 'kg',
LITRE = 'lt',
CENTIMETER = 'cm',
INCH = 'in',
METER = 'mt',
KILOMETER = 'km',
}
你有这样一门课,
export interface Unit {
Name: string;
Symbol: string;
}
然后,您可以创建一个如下所示的函数,将异构枚举映射到某个类型的对象,
export function getDefaultUnits() {
const myUnits = Object.entries(UnitEnum).map(x => {
return { Name: x[0], Symbol: x[1] } as Unit
})
console.log(myUnits);
return myUnits;
}
枚举是运行时存在的真实对象。所以你可以这样反向映射:
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