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

5

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

比如说,我有这样一个枚举:

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

我想以编程方式获取此枚举的名称。 我尝试了以下内容:
const enumType = MyEnum
console.log(enumType.constructor.name) // I expect this to return "MyEnum"

但它显示的是 "Object"。

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


2
你基本上是在问“如何获取变量的名称”,但实际上并没有办法做到。 - VLAZ
2
这个回答解决了你的问题吗?JavaScript中作为字符串的变量名 - VLAZ
@VLAZ 我想你误解了我的问题。我想获得枚举类型的名称(在这个例子中是MyEnum),而不是变量的名称(例如enumType)。我不明白它们怎么等价。 - Ivan Mushketyk
enum 转换为一个对象(变量)。请查看 - Aleksey L.
1
请访问以下链接,可能会解决您的问题:https://stackblitz.com/edit/typescript-enum-sample?file=index.ts - Dinshaw Raje
显示剩余4条评论
1个回答

9
首先,类型系统仅存在于编译时。当您有以下代码时:
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 = {}));

在TypeScript Playground中查看

执行后,您会得到一个名为MyEnum的变量,其中包含普通对象{ v1: "v1", v2: "v2" }

我之前说过TS将双向绑定键和值。上面的示例演示不好,所以这里有另一个示例:

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

将被转换为普通对象:

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

在TypeScript Playground中查看

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

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

无论如何,TypeScript不会将枚举名称编码为枚举的一部分,因此一旦运行时,您只有一个纯 JavaScript 变量可用。并不能在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),那么在函数体内,您无法引用传入的变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接