71
export enum MyEnum{
    Option1,
    Option2,
    Option3
}


string x = 'Option1';

MyEnum[x] throws an error:

Type string is not assignable to type MyEnum

however: MyEnum['Option1'] works.

I need to use MyEnum[x] though (in a method that returns a MyEnum), where x is a calculated value that results in one of the valid enum options, how do I go about it?

1

4 Answers 4

169

There are two ways to achieve this.

  1. If you still want to keep the powerful typechecking feature of TS, choose this

    MyEnum[x as keyof typeof MyEnum] 
    

typeof MyEnum will create an interface that represents the MyEnum object behind the scene and keyof will return a union of string literals, each one is the key in the MyEnum object (in other words, keyof will return a list of keys of a given object/class).

  1. Just simply turn off the type checking for the next line, which is similar to asserting the type of MyEnum to <any> as done in the @annepic 's answer
    // @ts-ignore 
    MyEnum[x] 
    

Extra note: Always turn on the Strict flag in tsconfig no matter what (u should only ignore type checking for a single line in very rare and special cases as done above). This configuration will force the developers to define the shape/type/structure/interface for everything, which makes the entire codebase super self-documenting and self-explanatory, especially for your future self and code maintainers. You can quickly infer how a class/object is structured and how a function is used with 100% certainty without even looking at its implementation. JSDoc specifies a set of very strict formatting rules for documenting JS code using comments, but these comments often end up being out of date because they are not changed along with the function evolution. Other benefits of the Strict flag are mentioned in the TypeScript primary doc.

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

5 Comments

Love the keyof typeof combo
Appreciate you actually explaining what keyof typeof is doing! :)
Clearly this post does not provide two elegant solutions as it suggests. I almost stop reading at @ts-ignore I really think this should be a last resort, there is always better solutions than that. Thanks for your 2nd one btw!
I ended up using: export function getEnumValueByKey<T extends Record<number, string>>( MyEnum: T, key: string ) { return MyEnum[key as keyof typeof MyEnum]; }
Based on the above: export const getEnumValueByKey = (key = 'defaultKey'): MyEnum => { return MyEnum[key as keyof typeof MyEnum]; };
5

Got it to work like this: return (<any>MyEnum)[x];

1 Comment

const key = calculatedkey(); return Object(MyEnum)[key];worked for me
4

You are declaring your string x variable wrong. You should do this:

export enum MyEnum{
    Option1,
    Option2,
    Option3
}


var x = 'Option1';
MyEnum[x];

1 Comment

thanks but it doesn't work like this. the x is calculated outside the method so maybe that's why. interesting to notice that <MyEnum> MyEnum[x] is syntax-error highlighted if I previously give x a value of 'Opt'+'ion1'. The concatenation gives a valid value, but typescript doesn't care to analyse it and directly shows a syntax error.
2

I think what you're looking for is to explicitly type the selected item in your enum as that enum. Example:

export enum MyEnum{
  Option1,
  Option2,
  Option3
}

function getEnum(x = 'Option1'):MyEnum {
  return <MyEnum>MyEnum[x];
}

The error you referenced "Type string is not assignable to type MyEnum" is actually coming from the function return type not matching your enum. A few of the other solutions convert the enum to an object but that isn't compatible with a function that has a return type of the same enum.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.