///
// All the following types are explained here:
// https://medium.freecodecamp.org/typescript-curry-ramda-types-f747e99744ab
// https://github.com/pirix-gh/medium/blob/master/types-curry-ramda/src/index.ts
declare namespace Tools {
type Head =
T extends [any, ...any[]]
? T[0]
: never;
type Tail =
((...t: T) => any) extends ((_: any, ...tail: infer TT) => any)
? TT
: [];
type HasTail =
T extends ([] | [any])
? false
: true;
type Last = {
0: Last>;
1: Head;
}[
HasTail extends true
? 0
: 1
];
type Length =
T['length'];
type Prepend =
((head: E, ...args: T) => any) extends ((...args: infer U) => any)
? U
: T;
type Drop = {
0: Drop, Prepend>;
1: T;
}[
Length extends N
? 1
: 0
];
type Cast = X extends Y ? X : Y;
type Pos =
Length;
type Next =
Prepend;
type Prev =
Tail;
type Iterator = {
0: Iterator, Next>;
1: From;
}[
Pos extends Index
? 1
: 0
];
type Reverse = {
0: Reverse], R>, Next>;
1: R;
}[
Pos extends Length
? 1
: 0
];
type Concat =
Reverse extends infer R ? Cast : never, T2>;
type Append =
Concat;
}
declare namespace Curry {
type GapOf =
T1[Tools.Pos] extends R.Placeholder
? Tools.Append], TN>
: TN;
type GapsOf = {
0: GapsOf extends infer G ? Tools.Cast : never, Tools.Next>;
1: Tools.Concat, T2> extends infer D ? Tools.Cast : never>;
}[
Tools.Pos extends Tools.Length
? 1
: 0
];
type PartialGaps = {
[K in keyof T]?: T[K] | R.Placeholder
};
type CleanedGaps = {
[K in keyof T]: NonNullable
};
type Gaps = CleanedGaps>;
type Curry any)> =
(...args: Tools.Cast>>, any[]>) =>
GapsOf> extends [any, ...any[]]
? Curry<(...args: GapsOf> extends infer G ? Tools.Cast : never) => ReturnType>
: ReturnType;
}