如何在运行时获取 TypeScript 枚举类型的名称?

Iva*_*tyk 4 enums typescript

我想以编程方式获取 TypeScript 枚举的名称。

说我有一个这样的枚举:

enum MyEnum {
  v1 = 'v1',
  v2 = 'v2',
}
Run Code Online (Sandbox Code Playgroud)

我想以编程方式获取此枚举的名称。我尝试了以下方法:

const enumType = MyEnum
console.log(enumType.constructor.name) // I expect this to return "MyEnum"
Run Code Online (Sandbox Code Playgroud)

但它显示“对象”。

有没有办法以编程方式获取 TypeScript 枚举的名称?

VLA*_*LAZ 5

首先,关闭类型系统仅在编译时存在。当你有

enum MyEnum {
  v1 = 'v1',
  v2 = 'v2',
}
Run Code Online (Sandbox Code Playgroud)

然后TypeScript知道枚举并确保这样做MyEnum['v1']是正确的,但会引发MyEnum['banana'].

然而,一旦代码被编译,你就有了纯 JavaScript。这是在运行时执行的内容。

枚举被编译为普通的 JavaScript 对象,键和值双重绑定。这样 TS 确保运行时枚举值的唯一性。给出的示例枚举变成:

var MyEnum;
(function (MyEnum) {
    MyEnum["v1"] = "v1";
    MyEnum["v2"] = "v2";
})(MyEnum || (MyEnum = {}));
Run Code Online (Sandbox Code Playgroud)

请参阅 TypeScript Playground

一旦执行,你会得到一个MyEnum保存普通对象的变量{ v1: "v1", v2: "v2" }

我确实说过 TS 会双重绑定键和值。上面的例子没有很好地展示它,所以这里是另一个:

enum ExampleEnum {
  Apple = 1,
  Banana = 2,
}
Run Code Online (Sandbox Code Playgroud)

将变成普通对象:

{ 
  1: "Apple", 
  2: "Banana", 
  Apple: 1, 
  Banana: 2 
}
Run Code Online (Sandbox Code Playgroud)

请参阅 TypeScript Playground

因此,两个键(Apple 和 Banana)都是唯一的,值(1 和 2)也是唯一的,因为它们都变成了对象的键,并且不能有重复的键。它还允许您执行MyEnum[MyEnum[key]]获取内容的key操作。

我不建议在您的枚举中有重复的值。技术上可行,但您可能不应该。如果你这样做,你会遇到问题MyEnum[MyEnum[key]]

无论如何,TypeScript 不会将枚举名称编码为枚举的一部分,因此一旦您处于运行时,您只需使用一个普通的 JavaScript 变量即可。并且您无法在 JavaScript 中获取变量的名称。充其量,您可以执行以下操作:

{ 
  1: "Apple", 
  2: "Banana", 
  Apple: 1, 
  Banana: 2 
}
Run Code Online (Sandbox Code Playgroud)

但是,这只是在作​​弊 - 您正在传递一个包含{ myVariable: 42 }. 这在您已经知道变量是什么时才有效,因此如果您想通过不同的变量间接获取名称,则几乎没有用:

function printVariableName(input) {
  console.log("Name:", Object.keys(input)[0]);
  console.log("Value:", Object.values(input)[0]);
}

var myVariable = 42;

printVariableName({myVariable});
Run Code Online (Sandbox Code Playgroud)

所以,你正在传递枚举,例如你有一个像这样的函数:

function printVariableName(input) {
  console.log("Name:", Object.keys(input)[0]);
  console.log("Value:", Object.values(input)[0]);
}

var myVariable = 42;
var myOtherVariable = myVariable;

printVariableName({myOtherVariable});
Run Code Online (Sandbox Code Playgroud)

然后,如果您doSomethingWithEnum(MyEnum)在函数体内调用then ,则无法取消引用传入的变量。