Reputation: 8295
I would like to programmatically get the name of a TypeScript enum.
Say I have an enum like this:
enum MyEnum {
v1 = 'v1',
v2 = 'v2',
}
I would like to get the name of this enum programmatically. I tried the following:
const enumType = MyEnum
console.log(enumType.constructor.name) // I expect this to return "MyEnum"
But it displays "Object" instead.
Is there a way to get name of a TypeScript enum programmatically?
Upvotes: 7
Views: 5127
Reputation: 29022
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 raises 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 = {}));
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
}
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 to 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 through 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, when 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.
Upvotes: 11