I was looking for an answer that can get an enum
from a string
, but in my case, the enums values had different string values counterpart. The OP had a simple enum for Color
, but I had something different:
enum Gender {
Male = 'Male',
Female = 'Female',
Other = 'Other',
CantTell = "Can't tell"
}
When you try to resolve Gender.CantTell
with a "Can't tell"
string, it returns undefined
with the original answer.
Another answer
Basically, I came up with another answer, strongly inspired by this answer:
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
(enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
Notes
- We take the first result of
filter
, assuming the client is passing a valid string from the enum. If it's not the case, undefined
will be returned.
- We cast
enumObj
to any
, because with TypeScript 3.0+ (currently using TypeScript 3.5), the enumObj
is resolved as unknown
.
Example of Use
const cantTellStr = "Can't tell";
const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell
Note: And, as someone pointed out in a comment, I also wanted to use the noImplicitAny
.
Updated version
No cast to any
and proper typings.
export const stringToEnumValue = <T, K extends keyof T>(enumObj: T, value: string): T[keyof T] | undefined =>
enumObj[Object.keys(enumObj).filter((k) => enumObj[k as K].toString() === value)[0] as keyof typeof enumObj];
Also, the updated version has a easier way to call it and is more readable:
stringToEnumValue(Gender, "Can't tell");