是否可以在 Typescript 中迭代 const 枚举?

Posted

技术标签:

【中文标题】是否可以在 Typescript 中迭代 const 枚举?【英文标题】:Is it possible in Typescript to iterate over a const enum? 【发布时间】:2018-02-07 02:24:25 【问题描述】:

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

示例

declare const enum FanSpeed 
    Off = 0,
    Low,
    Medium,
    High

理想的结果

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"
];

【问题讨论】:

【参考方案1】:

不,const enum 无法做到这一点。让我们从您的原始枚举开始并记录其值之一:

const enum FanSpeed 
    Off = 0,
    Low,
    Medium,
    High


console.log(FanSpeed.High);

TypeScript 编译器内联所有对FanSpeed 的引用,并将上面的代码编译成如下内容:

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

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

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

【讨论】:

是否可以使用 preserveConstEnums 编译器标志保留 const 枚举 是的,提到@TitianCernicova-Dragomir 非常重要。我从我的回答中链接到你的回答,以便他们看到你写的关于preserveConstEnums 我尝试在我的项目的 tsconfig.json 文件中设置"preserveConstEnums": true,但在使用referenced SO question 中的任一示例时,语法高亮仍然会突出显示错误。我正在使用 Visual Studio Code,但不确定需要应用哪些其他设置。 @Jim 正如我在使用 preserveConstEnums 的回答中提到的,枚举对象在那里,但访问起来有点棘手,因为编译器坚持认为它不存在。 @TitianCernicova-Dragomir,是的,事实上,我现在正在消化。我的枚举与许多其他接口和枚举一起放在interfaces.d.ts 文件中。阅读下面的帖子并尝试破译正确的组合以引用 for 循环中的特定枚举。【参考方案2】:

您可以使用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.)。有办法绕过它,但这取决于你的环境。 使用模块你可以这样写:

import  * as e from "./enumModule"

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

或者使用命名空间,你可以这样做:

namespace Enums  
    export const enum FanSpeed 
        Off = 0,
        Low,
        Medium,
        High
    

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

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

【讨论】:

是否需要在定义枚举的模块或使用枚举的模块上使用编译器标志,或两者兼而有之?如果枚举是从另一个项目导入的怎么办——如果不是,如果你[重新]从你自己的模块中导出它们会起作用吗?

以上是关于是否可以在 Typescript 中迭代 const 枚举?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vue JS Typescript 迭代一个对象 -> 数组 -> 对象

由Typescript数组实现的接口

如何在 TypeScript 中迭代自定义文字类型?

如何在 HTML 的 typescript 中迭代 JSON 数组?

使用TypeScript和Rollup构建迭代器

Ruby Enumerator的各种迭代