在Typescript中,是否可以迭代const枚举?
在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"} ];
在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
编译器选项。
关于编译器选项的使用,需要在定义枚举的模块中使用还是在使用枚举的模块中使用?如果枚举是从另一个项目导入的,是否也需要使用该选项?如果不是,将它们重新导出到自己的模块中会起作用吗?
在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文件中。