Scott Mallon
Scott Mallon

Reputation: 136

Typescript error when trying to map over Enum keys to produce JSX elements

For the life of my I can't figure this one out.

I have a simple enum, here:

export enum depositTypes {
  ACH = 42,
  Wire = 36,
  Check = 3,
  Credit = 2,
}

I want to map to option tags for a select, i.e.:

Object.keys(depositTypes).map((enumKey: keyof typeof depositTypes) => <option key={depositTypes.enumKey} label={enumKey} value={depositTypes.enumKey} />)

I get an error:

Argument of type '(enumKey: "ACH" | "Wire" | "Check" | "Credit") => JSX.Element' is not assignable to parameter of type '(value: string, index: number, array: string[]) => Element'. Types of parameters 'enumKey' and 'value' are incompatible. Type 'string' is not assignable to type '"ACH" | "Wire" | "Check" | "Credit"'.

Any ideas?

Upvotes: 3

Views: 3562

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42218

You are applying your assertion at the wrong place. Object.keys(depositTypes) is an array of string so its .map callback needs to be a function that can accept any string. Right now you have a mapper that can only accept keys of your enum, so it cannot be used to map string[].

Instead, we need to say that the array itself is an array of keys of your enum.

(Object.keys(depositTypes) as (keyof typeof depositTypes)[]).map( ... )

If you find yourself doing this a lot, you might want to extract it into a function:

const typedKeys = <T extends {}>(object: T): (keyof T)[] => {
  return Object.keys(object) as (keyof T)[];
}
typedKeys(depositTypes).map( ... )

There's an error in the code that you didn't spot earlier because of the previous error. You are using depositTypes.enumKey which is looking for the literal key 'enumKey' rather than depositTypes[enumKey] which looks for the key of this current variable. You want this:

(Object.keys(depositTypes) as (keyof typeof depositTypes)[]).map(
  enumKey => <option key={depositTypes[enumKey]} label={enumKey} value={depositTypes[enumKey]} />
)

Upvotes: 5

Related Questions