First, off the type system exists only at compile time. When you have
enum MyEnum {
v1 = 'v1',
v2 = 'v2',
}
Then TypeScript knows about the enums and ensures that doing MyEnum['v1']
is correct but raising a compile time problem for MyEnum['banana']
.
Once the code is compiled, however, you have pure JavaScript. This is what gets executed at runtime.
Enums get compiled to plain JavaScript objects double binding the keys and values. That way TS ensures the uniqueness of the enum values at runtime. The example enum given gets turned into:
var MyEnum;
(function (MyEnum) {
MyEnum["v1"] = "v1";
MyEnum["v2"] = "v2";
})(MyEnum || (MyEnum = {}));
See on TypeScript Playground
Once executed you get a MyEnum
variable that holds the plain object { v1: "v1", v2: "v2" }
I did say that TS will double-bind the keys and values. The example above doesn't demonstrate it well, so here is another one:
enum ExampleEnum {
Apple = 1,
Banana = 2,
}
will be turned into the plain object:
{
1: "Apple",
2: "Banana",
Apple: 1,
Banana: 2
}
See on TypeScript Playground
Thus both the keys (Apple and Banana) are unique, as would be the values (1 and 2), since they are all turned into keys of an object and you cannot have duplicate keys. It also allows you do do MyEnum[MyEnum[key]]
to fetch what key
is.
I don't suggest having duplicate values in your enum. Technically possible but you likely shouldn't. you'd have problems if you do MyEnum[MyEnum[key]]
At any rate, TypeScript does not encode the enum name as part of the enum, so once you're at runtime, you just have a plain JavaScript variable to work with. And you cannot get the name of a variable in JavaScript. At best, you can do something like:
function printVariableName(input) {
console.log("Name:", Object.keys(input)[0]);
console.log("Value:", Object.values(input)[0]);
}
var myVariable = 42;
printVariableName({myVariable});
However, this is just cheating a bit - you're passing an object which contains { myVariable: 42 }
. This only works if you already know what the variable is, so it's of little use if you want to get the name indirectly though a different variable:
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});
So, you you're passing around enums, e.g. you have a function like:
function doSomethingWithEnum(someEnum: MyEnum | MyOtherEnum): void {
//do something with the passed in `someEnum`
}
Then if you call doSomethingWithEnum(MyEnum)
then inside the body of the function you cannot de-reference what the passed in variable was.