-
Notifications
You must be signed in to change notification settings - Fork 0
/
tuple.ts
86 lines (79 loc) · 1.96 KB
/
tuple.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-len */
import { AnyArray, AnyFunction } from "../types";
import { Intersection } from "./intersection";
import { Length } from "./length";
/**
* @hidden
* @ignore
* @internal
*/
type LastOfUnion<T> = Intersection<
T extends never ? never : (arg: T) => T
> extends infer U
? U extends AnyFunction
? ReturnType<U>
: never
: never;
/**
* @hidden
* @ignore
* @internal
*/
type UnionToTuple<
TUnion,
TTuple extends AnyArray = []
> = LastOfUnion<TUnion> extends infer TLast
? Exclude<TUnion, TLast> extends never
? [TLast, ...TTuple]
: UnionToTuple<Exclude<TUnion, TLast>, [TLast, ...TTuple]>
: never;
/**
* Returns a Tuple for a given Union `T`
*
* @category Utility
* @example
* ```
* type A = Tuple<1|2|3> // === [1,2,3]
* ```
*/
export type Tuple<T> = Exclude<T, LastOfUnion<T>> extends never
? T extends Readonly<AnyArray>
? Length<T> extends never
? UnionToTuple<T>
: T
: UnionToTuple<T>
: UnionToTuple<T>;
type BuildPowersOf2LengthArrays<
N extends number,
R extends never[][]
> = R[0][N] extends never
? R
: BuildPowersOf2LengthArrays<N, [[...R[0], ...R[0]], ...R]>;
type ConcatLargestUntilDone<
N extends number,
R extends never[][],
B extends never[]
> = B["length"] extends N
? B
: [...R[0], ...B][N] extends never
? ConcatLargestUntilDone<
N,
R extends [R[0], ...infer U] ? (U extends never[][] ? U : never) : never,
B
>
: ConcatLargestUntilDone<
N,
R extends [R[0], ...infer U] ? (U extends never[][] ? U : never) : never,
[...R[0], ...B]
>;
type Replace<R extends any[], T> = { [K in keyof R]: T };
export type TupleOf<T, N extends number> = number extends N
? T[]
: {
[K in N]: BuildPowersOf2LengthArrays<K, [[never]]> extends infer U
? U extends never[][]
? Replace<ConcatLargestUntilDone<K, U, []>, T>
: never
: never;
}[N];