首先,类型系统仅存在于编译时。当您有以下代码时:
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 {
}
如果您调用doSomethingWithEnum(MyEnum)
,那么在函数体内,您无法引用传入的变量。
enum
转换为一个对象(变量)。请查看。 - Aleksey L.