Neoheurist Neoheurist - 3 months ago 63
TypeScript Question

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

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) because the line immediately following that does not error (referencing an enum member using a string literal):

enum State {
Happy = 0,
Sad = 1,
Drunk = 2
}

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["Happy"]); // no error
}


"noImplicitAny": true
is set in the project's
tsconfig.json
the error is detected

"noImplictAny": false
is set in the project's
tsconfig.json
no error is detected

I'm compiling with
"ntypescript": "^1.201603060104.1"


I'm now compiling with
"tsc": "1.8.10"


C:>npm install -g typescript

`-- typescript@1.8.10


Verifying installation:

C:\>tsc --version

Version 1.8.10


Here's my
tsconfig.json
file:

{
"compileOnSave": true,
"compilerOptions": {
"target": "ES5",
"module": "System",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": true,
"sourceMap": true,
"mapRoot": "map/",
"diagnostics": true
},
"exclude": [
"node_modules",
"typings"
]
}


Here's the compiler output:

C:\>tsc

test.ts(8,17): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

Answer

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.

Comments