1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | declare namespace Tools {
|
7 | type Head<T extends any[]> =
|
8 | T extends [any, ...any[]]
|
9 | ? T[0]
|
10 | : never;
|
11 |
|
12 | type Tail<T extends any[]> =
|
13 | ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any)
|
14 | ? TT
|
15 | : [];
|
16 |
|
17 | type HasTail<T extends any[]> =
|
18 | T extends ([] | [any])
|
19 | ? false
|
20 | : true;
|
21 |
|
22 | type Last<T extends any[]> = {
|
23 | 0: Last<Tail<T>>;
|
24 | 1: Head<T>;
|
25 | }[
|
26 | HasTail<T> extends true
|
27 | ? 0
|
28 | : 1
|
29 | ];
|
30 |
|
31 | type Length<T extends any[]> =
|
32 | T['length'];
|
33 |
|
34 | type Prepend<E, T extends any[]> =
|
35 | ((head: E, ...args: T) => any) extends ((...args: infer U) => any)
|
36 | ? U
|
37 | : T;
|
38 |
|
39 | type Drop<N extends number, T extends any[], I extends any[] = []> = {
|
40 | 0: Drop<N, Tail<T>, Prepend<any, I>>;
|
41 | 1: T;
|
42 | }[
|
43 | Length<I> extends N
|
44 | ? 1
|
45 | : 0
|
46 | ];
|
47 |
|
48 | type Cast<X, Y> = X extends Y ? X : Y;
|
49 |
|
50 | type Pos<I extends any[]> =
|
51 | Length<I>;
|
52 |
|
53 | type Next<I extends any[]> =
|
54 | Prepend<any, I>;
|
55 |
|
56 | type Prev<I extends any[]> =
|
57 | Tail<I>;
|
58 |
|
59 | type Iterator<Index extends number = 0, From extends any[] = [], I extends any[] = []> = {
|
60 | 0: Iterator<Index, Next<From>, Next<I>>;
|
61 | 1: From;
|
62 | }[
|
63 | Pos<I> extends Index
|
64 | ? 1
|
65 | : 0
|
66 | ];
|
67 |
|
68 | type Reverse<T extends any[], R extends any[] = [], I extends any[] = []> = {
|
69 | 0: Reverse<T, Prepend<T[Pos<I>], R>, Next<I>>;
|
70 | 1: R;
|
71 | }[
|
72 | Pos<I> extends Length<T>
|
73 | ? 1
|
74 | : 0
|
75 | ];
|
76 |
|
77 | type Concat<T1 extends any[], T2 extends any[]> =
|
78 | Reverse<Reverse<T1> extends infer R ? Cast<R, any[]> : never, T2>;
|
79 |
|
80 | type Append<E, T extends any[]> =
|
81 | Concat<T, [E]>;
|
82 | }
|
83 |
|
84 | declare namespace Curry {
|
85 | type GapOf<T1 extends any[], T2 extends any[], TN extends any[], I extends any[]> =
|
86 | T1[Tools.Pos<I>] extends R.Placeholder
|
87 | ? Tools.Append<T2[Tools.Pos<I>], TN>
|
88 | : TN;
|
89 |
|
90 | type GapsOf<T1 extends any[], T2 extends any[], TN extends any[] = [], I extends any[] = []> = {
|
91 | 0: GapsOf<T1, T2, GapOf<T1, T2, TN, I> extends infer G ? Tools.Cast<G, any[]> : never, Tools.Next<I>>;
|
92 | 1: Tools.Concat<TN, Tools.Drop<Tools.Pos<I>, T2> extends infer D ? Tools.Cast<D, any[]> : never>;
|
93 | }[
|
94 | Tools.Pos<I> extends Tools.Length<T1>
|
95 | ? 1
|
96 | : 0
|
97 | ];
|
98 |
|
99 | type PartialGaps<T extends any[]> = {
|
100 | [K in keyof T]?: T[K] | R.Placeholder
|
101 | };
|
102 |
|
103 | type CleanedGaps<T extends any[]> = {
|
104 | [K in keyof T]: NonNullable<T[K]>
|
105 | };
|
106 |
|
107 | type Gaps<T extends any[]> = CleanedGaps<PartialGaps<T>>;
|
108 |
|
109 | type Curry<F extends ((...args: any) => any)> =
|
110 | <T extends any[]>(...args: Tools.Cast<Tools.Cast<T, Gaps<Parameters<F>>>, any[]>) =>
|
111 | GapsOf<T, Parameters<F>> extends [any, ...any[]]
|
112 | ? Curry<(...args: GapsOf<T, Parameters<F>> extends infer G ? Tools.Cast<G, any[]> : never) => ReturnType<F>>
|
113 | : ReturnType<F>;
|
114 | }
|