17

I'm trying to find a way to convert the name of an enum to a string. If I have the Response enum below, how can I convert or extract 'Response' to a string? One of my functions takes any enum as input and I need the name, not the type of enum to execute other code.

enum Response 
{
    No = 0,
    Yes = 1 
}
3
  • 1
    Possible duplicate of Cast int to enum strings in Typescript Commented Apr 8, 2019 at 17:21
  • Also: stackoverflow.com/questions/18111657/… Commented Apr 8, 2019 at 17:22
  • 3
    @adiga I'm not interested in getting string values from the enum values. I'm trying to convert the actual name of the enum itself 'Response' in this example, as a string. Commented Apr 8, 2019 at 17:31

4 Answers 4

25

No, you can't convert an enum name to a string as type information is stored only during compilation. You have to pass additional parameters, specifying what enum are you using.


But you can use square brackets to convert numeric enum value to string and back:

Fiddle

enum YesNo {
    No = 0,
    Yes = 1, 
}

console.log(YesNo[YesNo.Yes]);
console.log(YesNo[YesNo.No]);
console.log(YesNo["Yes"]);
console.log(YesNo["No"]);
console.log(YesNo[1]);
console.log(YesNo[0]);

This code compiles into:

var YesNo;
(function (YesNo) {
YesNo[YesNo["No"] = 0] = "No";
YesNo[YesNo["Yes"] = 1] = "Yes";
})(YesNo || (YesNo = {}));
console.log(YesNo[YesNo.Yes]);
console.log(YesNo[YesNo.No]);
console.log(YesNo["Yes"]);
console.log(YesNo["No"]);
console.log(YesNo[1]);
console.log(YesNo[0]);

Sign up to request clarification or add additional context in comments.

4 Comments

For anyone else curious, YesNo[1] isn't an index reference but the value reference. So if enum YesNo {No = 0, Yes=8} then console.log(YesNo[8]) returns Yes. Furthermore, if the value isn't found, it returns undefined. And if multiple enums have the same value like enum YesNo {No = 8, Yes=8}.. it returns the last one defined in the enum so in this case it would return Yes.
This doesn't appear to work for enums with string values, only enums with number values.
@JeffreyTillwick, yep, numeric only.
So, not helpful, thanks.
3
Object.keys({ Response })[0]; // 'Response'

4 Comments

This is so clever and should be the accepted answer!
-1 : OK, neat trick, however ... If you're in a line of code where you have the type hardcoded (Response), then you don't need to convert it to a string. The challenge is to get the type name from the type after it's been passed into a function. This won't work: foo=func(Response) ... func getName(obj) { return Object.keys({ obj })[0] - and it won't work with typeof Response or similar syntax. Unless there is a better solution, it seems the typename must be passed in as a parameter, as so far it doesn't look like it can be inferred.
@TonyG Getting the name of a passed enum is the same as getting the name of passed variable - you can't do this as you are passing the reference or value, unless you use the trick I posted above and pass it as a parameter. OP wanted the way of getting the enum name and this is the only way of doing this.
@Tukkan : I agree to an extent and tried to remove my downvote, but it's not letting me. This is simply not a full solution to the OP's challenge. It's a hint at one part of how the problem can be solved, not an answer that can be accepted for implementation. Please see my answer which is fully implements your great answer here.
2

How about:

MyEnum[MyEnum.option1]

Comments

1

@Tukkan provided the right answer but it was too vague to use. Here is functional code that responds directly the OP.

enum Options {
    yes,
    no
}
type EnumType = Record<string, any>
function showEnumName(theEnum: EnumType) {
    const enumName = Object.keys(theEnum)[0] ?? ''
    console.log(enumName)
}
showEnumName({ Options })

Playground Link

Notes:

  1. The enum object is passed into the function, and the function derives the name from that object. Compare this to the inspirational response by Tukkan which requires that the process that gets the enum name must have the literal enum object - not a reference to it, which is what the OP and most of us needs.
  2. The index [0] isn't necessary. Corrected: This depends on tsconfig setting. I modified to avoid compile-time warning, which may or may not be good policy, but that's beyond the scope of this thread.
  3. Typing the object passed into the function is required to get this to work without compile-time errors. You can simply use (theEnum:any) but that would allow, um, anything in there. If you have a function that types the enum object as 'any' before passing it to this code, it's going to break. The object must be an enum. More rigorous typing is also beyond the scope of this thread.
  4. If you change the function to use syntax closer to what Tukkan suggested, here is what happens Playground :
function showEnumName(theEnum) {
    const enumName = Object.keys({ theEnum })
    console.log(enumName)
}
showEnumName({ Options })

The result is not "Options", it's "theEnum". That is, as Tukkan correctly noted, it's telling us the name of the variable that contains the data, which doesn't help inside the function when we want the name of the enum that was passed in.

If you like this Answer, please also upvote the answer by @Tukkan so that he gets points. This one would not have been possible without his. I cannot in good conscience take exclusive points when he provided the inspiration.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.