TypeScript TS7015 error when accessing an enum using a string type parameter

前端 未结 4 1715
执笔经年
执笔经年 2020-12-02 16:50

I am new to TypeScript and I don\'t understand the what I need to do to fix the line that generates the TS7015 error (referencing an enum member using a string variable) bec

相关标签:
4条回答
  • 2020-12-02 17:12

    I suspect it has to do with TS 1.8.x's new support for string literals in these situations. TS happens to know that "Happy" is a valid string index, but it doesn't know whether enumKey will be or not. You can fix it by casting it to an <any>, like so:

    function Emote(enumKey:string) {
        console.log(State[enumKey]); // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
        console.log(State["Melancholy"]); // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
        console.log(State["Happy"]); // no error
        console.log(State[<any>enumKey]); // no error
        console.log(State[<any>"Melancholy"]); // no error
    }
    

    (BTW, I think this is new: I couldn't reproduce this error with 1.8.9, but as soon as I upgraded to 1.8.10, I could.)

    Also interestingly, I would have expected this to work without the error, but it doesn't:

    function TypedEmote(enumKey:'Happy'|'Sad'|'Drunk'){
        console.log(State[enumKey]);
    }
    

    Must be something about the TS spec I don't understand, or perhaps they just haven't gotten around to fixing that bit yet.

    0 讨论(0)
  • 2020-12-02 17:19

    You can prevent this error with the compiler option without loosing the whole strict null checks

    "suppressImplicitAnyIndexErrors": true
    
    0 讨论(0)
  • 2020-12-02 17:27

    If you're using TypeScript 2.1+, you can change enumKey's type to keyof typeof State, like this:

    function Emote(enumKey: keyof typeof State) {...}
    

    or, if the function's input is required to be a string, this:

    var state : State = State[enumKey as keyof typeof State];
    

    Explanation:

    The error is generated because TypeScript, being an arbitrary string, doesn't know whether enumKey is the name of a member of State. TypeScript 2.1+ introduced the keyof operator which returns a union of the known, public property names of a type. Using keyof allows us to assert that the property is indeed in the target object.

    However, when you create an enum, TypeScript actually produces both a type (which is always a subtype of number) and a value (the enum object that you can reference in expressions). When you write keyof State, you're actually going to get a union of the literal property names of number. To instead get the property names of the enum object, you can use keyof typeof State.

    Sources:

    https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types

    0 讨论(0)
  • 2020-12-02 17:30
    var stateName = "Happy"
    var state = <State>parseInt(State[<any>stateName]);
    

    This is what I had to do to make the compiler happy

    0 讨论(0)
提交回复
热议问题