I would like to declare a type-enforced array of items and be able to derive a union type from it. This pattern works if you do not explicitly give a type to the items in the array. I am not sure how to best explain it so here is an example:
EXAMPLE 1
type Pair = {
key: string;
value: number;
};
const pairs: ReadonlyArray<Pair> = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']
EXAMPLE 2
type Data = {
name: string;
age: number;
};
const DataRecord: Record<string, Data> = {
foo: { name: 'Mark', age: 35 },
bar: { name: 'Jeff', age: 56 },
} as const;
type Keys = keyof typeof DataRecord;
Here is an example of deriving the keys when using as const
. I want this same behavior but with the array being explicitly typed.
const pairs = [
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const;
type Keys = typeof pairs[number]['key']; // "foo" | "bar"
desired value of keys: "foo"|"bar"
actual value of keys: string
To convert an array of strings into a string literal union type in TypeScript, you can first define the array of strings then make the array as readonly using the as const keyword, and then use the typeof operator on all the values contained in the array.
The typeof operator returns "object" for objects, arrays, and null.
The type object {} represents a 0-field object. The only legal value of this type is an empty object: {} .
The usual approaches are:
pairs
by omitting the explicit type ReadonlyArray<Pair>
(see answer)key
in Pair
the type "foo"|"bar"
If you don't want to do this, then the only way to infer your keys and restrict the type of pairs
is to use a helper function. The Pair
type will also be made generic to save the given key
string literal types. You can use an IIFE to make the assignment compact:
type Pair<K = string> = {
key: K;
value: number;
};
const pairs = (<T>(p: readonly Pair<T>[]) => p)([
{ key: 'foo', value: 1 },
{ key: 'bar', value: 2 },
] as const) // readonly Pair<"foo" | "bar">[]
type Keys = typeof pairs[number]['key'] // "foo" | "bar"
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With