简答:
只有数字枚举可以有计算成员,但这个表达式的类型是“字符串”。如果您不需要详尽检查,请考虑改用对象字面量。
长答案:
很遗憾,你可以做到,但这并不意味着你应该这样做:
const colors = ['R', 'G', 'B']
enum Color { }
const result = colors.reduce((acc, elem) => {
return {
...acc,
[elem]: elem
}
}, Color)
在这种情况下,您将失去类型安全性。 TS,无法确定 Color 枚举的类型。
type O = keyof typeof result // never, TS don't know anymore nothing about this type
enum OkColor{
R='R',
G='G',
B='B'
}
type O2 = keyof typeof OkColor // 'R' | 'G' | 'B' ---> here TS knows the keys of enum
尽量避免enums。
最好的方法是使用常量对象:
const colors = {
R:'R',
G: 'G',
B: 'B',
} as const;
如果您仍想使用枚举,请至少使用 const 关键字。见docs
const enum X {
A='A'
}
以下是将数组安全转换为只读对象的代码:
const colors = ['R', 'G', 'B'] as const;
type ValuesOfArray<T extends ReadonlyArray<any>> = T[number]
type ToObj<K extends string> = {
[P in K]: P
}
type ToEnum = ToObj<ValuesOfArray<typeof colors>>
const toPseudoEnum = <T extends readonly any[], K extends ValuesOfArray<T>>(arr: T):Readonly<ToObj<K>> => {
return arr.reduce((acc, elem) => {
return {
...acc,
[elem]: elem
}
}, {})
}
const customEnum = toPseudoEnum(colors); // {R:'R',G:'G',B:'B'}