简体   繁体   中英

Get TypeScript enum numeric value by member name

I'm converting one of my JavaScript apps to TypeScript and I've got a problem: I've got a numeric enum, AnswerKeys and a key , "C" . I'd like to get the member's value, "2" , so I tried using AnswerKeys[key] .

enum AnswerKeys {
  'A' = 0,
  'B',
  'C',
}
let key = 'C'
let answer = AnswerKeys[key]
// it should log 2
console.log(answer)

It would work but I receive the following TypeScript error:

Element implicitly has an 'any' type because index expression is not of type 'number'.

It seems it has a problem with key not being a number. Other answers suggested adding as any assertion or just adding "suppressImplicitAnyIndexErrors": true to the config file, and while these do suppress the error, it's not what I want.

The following works but accepts any key and I only want to accept strings:

let answer = AnswerKeys[key as any]

I also tried keyOf AnswerKeys but it results in an extra error :

enum AnswerKeys {
  'A' = 0,
  'B',
  'C',
}
let key: keyof AnswerKeys = 'C'
let answer = AnswerKeys[key]
console.log(answer)

Type '"C"' is not assignable to type '"toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"'.(2322)

Is there any way to annotate it correctly?

To get a union of all of the enum values, you can use keyof typeof Enum . This is because keyof Enum gives you the keys of the object Enum (as AnswerKeys is technically just an object/value), whereas you want the keys of the type Enum .

Using your example, the following runs with no errors:

enum AnswerKeys {
  'A' = 0,
  'B',
  'C',
}
let key: keyof typeof AnswerKeys = 'C'
let answer = AnswerKeys[key]
console.log(answer)

Use any of the following methods:

1. Modify tsconfig.json
Add/uncomment "suppressImplicitAnyIndexErrors": true in tsconfig.json .
In newer versions of Typescript, it is called noImplicitAny .
Documentation can be found here .

2. key as keyof typeof AnswerKeys

let key = 'C'
let answer = AnswerKeys[key as keyof typeof AnswerKeys]

3. Disable linting for the line using @ts-ignore

let key = 'C'
// @ts-ignore
let answer = AnswerKeys[key]

4. Set key to type any

let key: any = 'C'
let answer = AnswerKeys[key]

Sources: https://stackoverflow.com/a/40997325/ & https://stackoverflow.com/a/66117678/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM