首先,关闭类型系统只存在于编译时。当你有
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),那么在函数体内你不能取消引用传入的变量。