2

Suppose that I have an array const a = ['apple', 'orange'].

Basically, I want to convert this to something like:

type MyType = 'apple' | 'orange';

I don't know if this is possible with Typescript. I have searched a lot and haven't find a way to do it.

davidaap
  • 1,569
  • 1
  • 18
  • 43

1 Answers1

0

If you just write const a = ['apple', 'orange'], the compiler will infer a to be of type string[], and any information about the literal "apple" or "orange" values will be lost. This is reasonable default behavior since, quite often, people want to add/remove string values from a string array. But it's not helpful for your use case; it's too wide. You want the compiler to infer a narrower type for a.

One way to do this is with a const assertion:

const a = ['apple', 'orange'] as const;
// const a: readonly ["apple", "orange"]

Now the compiler infers that a is a readonly tuple of the literal string types "apple" and "orange", in that order.


At this point you have enough information to compute MyType:

type MyType = (typeof a)[number];
// type MyType = "apple" | "orange"

This is using the typeof type operator to find the type of a (which is readonly ["apple", "orange"]), and then perform an indexed access on it with the number index. Since (typeof a) is an array type, then if you index into a with a number, you will get a value of the "apple" or "orange" literal types. Hence, (typeof a)[number] is "apple" | "orange".

Playground link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360