【问题标题】:How to get the name of TypeScript enum type in runtime?如何在运行时获取 TypeScript 枚举类型的名称?
【发布时间】:2020-01-20 11:53:32
【问题描述】:

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

假设我有一个这样的枚举:

enum MyEnum {
  v1 = 'v1',
  v2 = 'v2',
}

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

const enumType = MyEnum
console.log(enumType.constructor.name) // I expect this to return "MyEnum"

但它显示的是“对象”。

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

【问题讨论】:

  • 您实际上是在问“如何获取变量的名称”,没有办法做到这一点。
  • 这能回答你的问题吗? Variable name as a string in Javascript
  • @VLAZ 我想你误解了我的问题。我想获取 Enum 类型的名称(在本例中为 MyEnum),而不是变量的名称(在本例中为 enumType)。我看不出它们是如何等效的。
  • enum 传递到一个对象(变量)。有一个look
  • 请通过此链接可能会解决您的问题stackblitz.com/edit/typescript-enum-sample?file=index.ts

标签: typescript enums


【解决方案1】:

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

enum MyEnum {
  v1 = 'v1',
  v2 = 'v2',
}

然后 TypeScript 知道枚举并确保执行 MyEnum['v1'] 是正确的,但会引发 MyEnum['banana'] 的编译时间问题。

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

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

var MyEnum;
(function (MyEnum) {
    MyEnum["v1"] = "v1";
    MyEnum["v2"] = "v2";
})(MyEnum || (MyEnum = {}));

See on TypeScript Playground

执行后,您将获得一个 MyEnum 变量,其中包含普通对象 { v1: "v1", v2: "v2" }

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

enum ExampleEnum {
  Apple = 1,
  Banana = 2,
}

将变成普通对象:

{ 
  1: "Apple", 
  2: "Banana", 
  Apple: 1, 
  Banana: 2 
}

See on TypeScript Playground

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

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

无论如何,TypeScript 不会将枚举名称编码为枚举的一部分,因此在运行时,您只需使用一个普通的 JavaScript 变量即可。和you cannot get the name of a variable in JavaScript。充其量,您可以执行以下操作:

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

var myVariable = 42;

printVariableName({myVariable});

但是,这只是作弊 - 你传递了一个包含 { myVariable: 42 } 的对象。这个只有在你已经知道变量是什么的情况下才有效,所以如果你想通过一个不同的变量间接获得名字,它就没有什么用处了:

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});

所以,你是在传递枚举,例如你有这样的功能:

function doSomethingWithEnum(someEnum: MyEnum | MyOtherEnum): void {
  //do something with the passed in `someEnum`
}

如果你调用doSomethingWithEnum(MyEnum),那么在函数体内你不能取消引用传入的变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 2015-12-22
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多