Issue
Given the following TypeScript type:
type options =
| {label: "a", fields: Array<Object>}
| {label: "b", fields: Array<Object>}
| {label: "c", fields: Array<Object>}
;
Is there a way to use the options
type to generate a value (e.g. ["a", "b", "c"]
) that can be used at runtime?
If so, how can ["a", "b", "c"]
be generated from the options
type?
Solution
As others have suggested – you can’t generate a value from a type, as the concepts of types don’t exist at runtime.
What you could do instead, is generate your types from values. The typeof
operation is helpful here
const labels = ["a", "b", "c"] as const;
type PossibleValues = typeof labels[number]; // type PossibleValues = "a" | "b" | "c"
type Options = {label: PossibleValues, fields: Array<unknown>};
const a: Options = {
label: "a",
fields: [],
}
const notRight: Options = {
label: "fobar", //Type '"fobar"' is not assignable to type '"a" | "b" | "c"'.(2322)
fields: [],
}
What’s happening here:
const labels = ["a", "b", "c"] as const;
We need to use the as const
assertion here to tell typescript that labels isn’t an array of any ol’ strings, it’s an array of these specific strings.
type PossibleValues = typeof labels[number];
We are doing two things here:
- First we are saying ‘what is the type of
labels
‘, which isArray<"a" | "b" | "c">
. - Next we say, ‘what is the type of of the things accessible by
number
‘. (ie. what are all the possible types of the arrays contents. Remember an array also has prototype functions like .forEach etc).
Now we can create our Options type.
Answered By – dwjohnston
Answer Checked By – Terry (BugsFixing Volunteer)