1 | /**
|
2 | Creates a read-only tuple of type `Element` and with the length of `Length`.
|
3 |
|
4 | @private
|
5 | @see `ReadonlyTuple` which is safer because it tests if `Length` is a specific finite number.
|
6 | */
|
7 | type BuildTupleHelper<Element, Length extends number, Rest extends Element[]> =
|
8 | Rest['length'] extends Length ?
|
9 | readonly [...Rest] : // Terminate with readonly array (aka tuple)
|
10 | BuildTupleHelper<Element, Length, [Element, ...Rest]>;
|
11 |
|
12 | /**
|
13 | Create a type that represents a read-only tuple of the given type and length.
|
14 |
|
15 | Use-cases:
|
16 | - Declaring fixed-length tuples with a large number of items.
|
17 | - Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types.
|
18 | - Creating a tuple of coordinates with a static length, for example, length of 3 for a 3D vector.
|
19 |
|
20 | @example
|
21 | ```
|
22 | import {ReadonlyTuple} from 'type-fest';
|
23 |
|
24 | type FencingTeam = ReadonlyTuple<string, 3>;
|
25 |
|
26 | const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];
|
27 |
|
28 | const homeFencingTeam: FencingTeam = ['George', 'John'];
|
29 | //=> error TS2322: Type string[] is not assignable to type 'FencingTeam'
|
30 |
|
31 | guestFencingTeam.push('Sam');
|
32 | //=> error TS2339: Property 'push' does not exist on type 'FencingTeam'
|
33 | ```
|
34 |
|
35 | @category Utilities
|
36 | */
|
37 | export type ReadonlyTuple<Element, Length extends number> =
|
38 | number extends Length
|
39 | // Because `Length extends number` and `number extends Length`, then `Length` is not a specific finite number.
|
40 | ? readonly Element[] // It's not fixed length.
|
41 | : BuildTupleHelper<Element, Length, []>; // Otherwise it is a fixed length tuple.
|