UNPKG

3.24 kBTypeScriptView Raw
1/// <reference path="./index.d.ts" />
2
3// All the following types are explained here:
4// https://medium.freecodecamp.org/typescript-curry-ramda-types-f747e99744ab
5// https://github.com/pirix-gh/medium/blob/master/types-curry-ramda/src/index.ts
6declare 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
84declare 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}