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

21 浏览
0 Comments

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

类似于这个问题,但枚举被标记为常量:如何迭代或生成一个来自常量枚举的数组?\n示例\n

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

\n期望结果\n

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

0
0 Comments

在TypeScript中,使用常量枚举进行迭代是可能的吗?这个问题的出现是因为TypeScript在生成JavaScript代码时会替换掉枚举的值,而无法直接使用for循环遍历枚举的属性。有一些解决方法,具体取决于你的环境。

一种解决方法是使用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编译器选项。

关于编译器选项的使用,需要在定义枚举的模块中使用还是在使用枚举的模块中使用?如果枚举是从另一个项目导入的,是否也需要使用该选项?如果不是,将它们重新导出到自己的模块中会起作用吗?

0
0 Comments

在TypeScript中,无法使用const enum进行迭代。让我们从最初的enum开始,记录其中一个值:

const enum FanSpeed {
    Off = 0,
    Low,
    Medium,
    High
}
console.log(FanSpeed.High);

TypeScript编译器会将所有对FanSpeed的引用内联,并将上述代码编译为类似于以下内容:

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

换句话说,由于使用了const enum,运行时实际上没有FanSpeed对象存在,只有简单的数值字面量在传递。对于常规的非const enum,FanSpeed将作为一个值存在,可以迭代其键。

编辑:如果您可以更改项目的编译器设置,请参考Titian在下面的答案中提供的关于preserveConstEnums标志的非常有用的信息,这将导致创建一个FanSpeed对象,从而为您提供迭代enum的方法。

是的,这一点非常重要,-Dragomir。我在我的答案中链接了你的答案,以便他们看到你在preserveConstEnums方面的解释。

我尝试在项目的tsconfig.json文件中设置"preserveConstEnums": true,但是当使用引用的SO问题中的任何示例时,语法高亮仍然会显示错误。我正在使用Visual Studio Code,不确定是否需要应用其他设置。

如我在我的答案中提到的,使用preserveConstEnums,enum对象是存在的,但访问起来有些棘手,因为编译器坚称它不存在。

-Dragomir,是的,我正在消化这个问题。实际上,我的enum放在一个interfaces.d.ts文件中,其中还有许多其他接口和enum。根据你下面的帖子,我试图解读出在for循环中引用那个特定enum的正确组合。

d.ts文件不会生成代码,它们只用于定义。您应该将其移动到.ts文件中。

0