UNPKG

1.69 kBTypeScriptView Raw
1/**
2Convert a tuple/array into a union type of its elements.
3
4This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself.
5
6@example
7```
8import type {TupleToUnion} from 'type-fest';
9
10const destinations = ['a', 'b', 'c'] as const;
11
12type Destination = TupleToUnion<typeof destinations>;
13//=> 'a' | 'b' | 'c'
14
15function verifyDestination(destination: unknown): destination is Destination {
16 return destinations.includes(destination as any);
17}
18
19type RequestBody = {
20 deliverTo: Destination;
21};
22
23function verifyRequestBody(body: unknown): body is RequestBody {
24 const deliverTo = (body as any).deliverTo;
25 return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
26}
27```
28
29Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided.
30
31@example
32```
33const destinations = ['a', 'b', 'c'] as const;
34
35type Destination = typeof destinations[number];
36//=> 'a' | 'b' | 'c'
37
38const erroringType = new Set(['a', 'b', 'c']);
39
40type ErroringType = typeof erroringType[number];
41//=> Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
42
43const numberBool: { [n: number]: boolean } = { 1: true };
44
45type NumberBool = typeof numberBool[number];
46//=> boolean
47```
48
49@category Array
50*/
51export type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;