Say I have an array const arr = ['key1', 'key2', 'key3']. How do I make a type like
type Test = { str: Items<arr> }
so that Test types have a str attribute that is either 'key1', 'key2', 'key3'?
By default TypeScript will infer arr type as string[]. If we want to infer it as ['key1', 'key2', 'key3'] we can either do as const or as ['key1', 'key2', 'key3']
To get union type of object values you need to pass a union of object indices as a type index. type ValueOf<T> = T[keyof T]. But in this case we have an array so just [number] will do.
const arr = ['key1', 'key2', 'key3'] as const;
type Test = { str: typeof arr[number] }
const test: Test = {
str: 'key1'
}
str's type as (property) str: string instead of the expected 'key1' | 'key2' | 'key3'as const or as ['key1', 'key2', 'key3'] at the end of the arr definition?as const mean here?as const is a const assertion which tells TypeScript to treat this variable as a readonly constant. In case of readonly constant TypeScript can safely infer the type as literal ['key1', 'key2', 'key3'] because assertion guarantees that the array will not be mutated later in the code.Define a type for just the values of str property separately. Then use it when defining your custom type Type.
Something like the following:
type Str = 'key1' | 'key2' | 'key3';
type Type = { str: Str }
arr: Str[] instead. Won't mark as answer since it technically doesn't answer the question. Thanks tho!Test types to have an str attribute that is of either of those 3 values. This means Test types, technically, are objects with the str field. (they can have other fields). And if the value of the str attribute is either of those 3 values, the taking the type Str is enough, and not the type Str[] because Str[] will require an array. do you understand?