1 | /**
|
2 | Extracts the type of the last element of an array.
|
3 |
|
4 | Use-case: Defining the return type of functions that extract the last element of an array, for example [`lodash.last`](https://lodash.com/docs/4.17.15#last).
|
5 |
|
6 | @example
|
7 | ```
|
8 | import type {LastArrayElement} from 'type-fest';
|
9 |
|
10 | declare function lastOf<V extends readonly any[]>(array: V): LastArrayElement<V>;
|
11 |
|
12 | const array = ['foo', 2];
|
13 |
|
14 | typeof lastOf(array);
|
15 | //=> number
|
16 |
|
17 | const array = ['foo', 2] as const;
|
18 |
|
19 | typeof lastOf(array);
|
20 | //=> 2
|
21 | ```
|
22 |
|
23 | @category Array
|
24 | @category Template literal
|
25 | */
|
26 | export type LastArrayElement<Elements extends readonly unknown[], ElementBeforeTailingSpreadElement = never> =
|
27 | // If the last element of an array is a spread element, the `LastArrayElement` result should be `'the type of the element before the spread element' | 'the type of the spread element'`.
|
28 | Elements extends readonly []
|
29 | ? ElementBeforeTailingSpreadElement
|
30 | : Elements extends readonly [...infer U, infer V]
|
31 | ? V
|
32 | : Elements extends readonly [infer U, ...infer V]
|
33 | // If we return `V[number] | U` directly, it would be wrong for `[[string, boolean, object, ...number[]]`.
|
34 | // So we need to recurse type `V` and carry over the type of the element before the spread element.
|
35 | ? LastArrayElement<V, U>
|
36 | : Elements extends ReadonlyArray<infer U>
|
37 | ? U | ElementBeforeTailingSpreadElement
|
38 | : never;
|