Created
November 24, 2021 14:32
-
-
Save rubencodes/b0a61efea0fd53676efb73c957ac5808 to your computer and use it in GitHub Desktop.
TypeScript Currying
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type AnyArray = any[]; | |
type AnyArrayWithItems = [any, ...any]; | |
type AnyFunction<Arguments extends any[] = any[]> = (...args: Arguments) => any; | |
// The type of the first item in an array. | |
// Input: `[1, 2, 3]` | |
// Output: `1` | |
type Head<SomeArray extends AnyArray> = SomeArray extends AnyArrayWithItems | |
? SomeArray[0] | |
: never; | |
// The type of an array after removing the first element. | |
// Input: `[1, 2, 3]` | |
// Output: `[2, 3]` | |
type Tail<SomeArray extends AnyArray> = AnyFunction<SomeArray> extends ( | |
_: any, | |
...args: infer Remainder | |
) => any | |
? Remainder | |
: never; | |
// A type representing the length of an array. | |
// Input: `[1, 2, 3]` | |
// Output: `3` | |
type Length<SomeArray extends AnyArray> = SomeArray["length"]; | |
// A true type if an array is of a certain length, false otherwise. | |
// Input: `[1, 2, 3]`, `3` | |
// Output: `true` | |
type HasLength< | |
SomeArray extends AnyArray, | |
Num extends number, | |
> = Length<SomeArray> extends Num ? true : false; | |
// A curried version of the function type. | |
// Input: `(x, y) => z` | |
// Output: `(x) => (y) => z`. | |
type Curried<Func extends AnyFunction> = ( | |
arg: Head<Parameters<Func>>, | |
) => HasLength<Parameters<Func>, 1> extends true | |
? ReturnType<Func> | |
: Curried<(...args: Tail<Parameters<Func>>) => ReturnType<Func>>; | |
declare function curry<Func extends AnyFunction>(func: Func): Curried<Func>; | |
const toCurry = (name: string, age: number, single: boolean) => true; | |
curry(toCurry)("Ruben")(21)(true); // true | |
curry(toCurry)("Foo")("Bar")("Baz"); // TypeError |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment