2

Here is the TypeScript playground example for this question, which only has the bare minimum required for this question.

Here is the real world example of where this comes up: I have an enum

export enum OrderType {
  Market = 'MARKET',
  Limit = 'LIMIT',
}

And then I have an input field

export const TypeInputInner = ({ onChange, value }: Props) => {
  return (
    <Select style={{ width: 150, margin: 5 }} value={value} onChange={onChange}>
      {Object.keys(OrderType).map(type => (
        <Option key={type} value={OrderType[type]}>
          {type}
        </Option>
      ))}
    </Select>
  );
};

There is a TS error on that OrderType[type] part:

Error:(16, 45) TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

Why is this? Isn't the enum just an object?, ie

{
  Market: "MARKET",
  Limit: "LIMIT"
}

Where do numbers come in here?

Btw, I know that if I use type as any the TS errors go away.

evianpring
  • 3,316
  • 1
  • 25
  • 54

1 Answers1

3

The primary issue is that the return type of Object.keys(obj) is string[] and not Array<keyof typeof obj>. This is the desired and intended behavior because TypeScript cannot be sure that an object has only the keys it knows about.

If you know for sure that your object only has known keys in it, then you can use a type assertion to tell the compiler that it can treat Object.keys() as a more restricted set, as in:

(Object.keys(OrderType) as Array<keyof typeof OrderType>).map(type =>
  console.log(OrderType[type]) // okay now
);

The reason it was complaining that type isn't a number is probably because enum types have a numeric index in order to implement reverse mappings for any numeric values in your enum. Of course the example here is purely a string enum but I guess they put numeric indexes on every enum object type:

const hmm = OrderType[123]; // string 

Anyway, when type was just string, OrderType[type] is any because there is no string index signature, and the compiler was warning that the only index signature on the object is numeric.


Okay, hope that helps; good luck!

Link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360