在Typescript中可以迭代一个const枚举吗?

Is it possible in Typescript to iterate over a const enum?

与此问题类似,但枚举标记为常量:如何迭代或从常量枚举生成数组?

例子

1
2
3
4
5
6
declare const enum FanSpeed {
    Off = 0,
    Low,
    Medium,
    High
}

令人满意的结果

1
2
3
4
5
6
7
type enumItem = {index: number, value: string};
let result: Array<enumItem> = [
    {index: 0, value:"Off"},
    {index: 1, value:"Low"},
    {index: 2, value:"Medium"},
    {index: 3, value:"High"}
];


不,这是不可能与一个const enum的。让我们从原始枚举开始,并记录其值之一:

1
2
3
4
5
6
7
8
const enum FanSpeed {
    Off = 0,
    Low,
    Medium,
    High
}

console.log(FanSpeed.High);

typescript编译器将所有对FanSpeed的引用导入,并将上述代码编译成如下代码:

1
console.log(3 /* High */);

换句话说,由于您使用的是const enum,因此在运行时实际上不存在FanSpeed对象,而是传递简单的数字文本。使用常规的非常量enumFanSpeed将作为一个值存在,您可以迭代它的键。

编辑:如果您可以更改项目的编译器设置,请参阅下面的Titian的答案,以获取有关preserveConstEnums标志的非常有用的信息,该标志将导致实际创建FanSpeed对象,从而为您提供在枚举上迭代的方法。


您可以使用preserveConstEnums编译器标志。这将在javascript中发出枚举对象,但替换所有值。问题是,不能简单地对属性执行for,因为typescript会生成一个错误(enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.)。有很多方法可以绕过它,但这取决于你的环境。使用模块,您可以这样编写它:

1
2
3
4
5
import  * as e from"./enumModule"

for(var prop in (e as any)['FanSpeed']) {
  console.log(prop) ;
}

或者使用一个名称空间,你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
namespace Enums {
    export const enum FanSpeed {
        Off = 0,
        Low,
        Medium,
        High
    }
}
for(var prop in (Enums as any)['FanSpeed']) {
    console.log(prop) ;
}

注意:无论哪种情况,都必须首先使用preserveconstenums编译器选项,