/// // 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; type ValueOfRecord = R extends Record ? T : never; } 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; }