1 | import type {IfAny} from './if-any';
|
2 | import type {IfNever} from './if-never';
|
3 | import type {UnknownArray} from './unknown-array';
|
4 |
|
5 | /**
|
6 | @see {@link IsTuple}
|
7 | */
|
8 | export type IsTupleOptions = {
|
9 | /**
|
10 | Consider only fixed length arrays as tuples.
|
11 |
|
12 | - When set to `true` (default), arrays with rest elements (e.g., `[1, ...number[]]`) are _not_ considered as tuples.
|
13 | - When set to `false`, arrays with at least one non-rest element (e.g., `[1, ...number[]]`) are considered as tuples.
|
14 |
|
15 | @default true
|
16 |
|
17 | @example
|
18 | ```ts
|
19 | import type {IsTuple} from 'type-fest';
|
20 |
|
21 | type Example1 = IsTuple<[number, ...number[]], {fixedLengthOnly: true}>;
|
22 | //=> false
|
23 |
|
24 | type Example2 = IsTuple<[number, ...number[]], {fixedLengthOnly: false}>;
|
25 | //=> true
|
26 | ```
|
27 | */
|
28 | fixedLengthOnly?: boolean;
|
29 | };
|
30 |
|
31 | /**
|
32 | Returns a boolean for whether the given array is a tuple.
|
33 |
|
34 | Use-case:
|
35 | - If you want to make a conditional branch based on the result of whether an array is a tuple or not.
|
36 |
|
37 | Note: `IsTuple` returns `boolean` when instantiated with a union of tuple and non-tuple (e.g., `IsTuple<[1, 2] | number[]>`).
|
38 |
|
39 | @example
|
40 | ```ts
|
41 | import type {IsTuple} from 'type-fest';
|
42 |
|
43 | type Tuple = IsTuple<[1, 2, 3]>;
|
44 | //=> true
|
45 |
|
46 | type NotTuple = IsTuple<number[]>;
|
47 | //=> false
|
48 |
|
49 | type TupleWithOptionalItems = IsTuple<[1?, 2?]>;
|
50 | //=> true
|
51 |
|
52 | type RestItemsNotAllowed = IsTuple<[1, 2, ...number[]]>;
|
53 | //=> false
|
54 |
|
55 | type RestItemsAllowed = IsTuple<[1, 2, ...number[]], {fixedLengthOnly: false}>;
|
56 | //=> true
|
57 | ```
|
58 |
|
59 | @see {@link IsTupleOptions}
|
60 |
|
61 | @category Type Guard
|
62 | @category Utilities
|
63 | */
|
64 | export type IsTuple<
|
65 | TArray extends UnknownArray,
|
66 | Options extends IsTupleOptions = {fixedLengthOnly: true},
|
67 | > =
|
68 | IfAny<TArray, boolean, IfNever<TArray, false,
|
69 | TArray extends unknown // For distributing `TArray`
|
70 | ? number extends TArray['length']
|
71 | ? Options['fixedLengthOnly'] extends false
|
72 | ? IfNever<keyof TArray & `${number}`,
|
73 | TArray extends readonly [...any, any] ? true : false, // To handle cases where a non-rest element follows a rest element, e.g., `[...number[], number]`
|
74 | true>
|
75 | : false
|
76 | : true
|
77 | : false
|
78 | >>;
|