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