Last active
April 10, 2023 21:00
-
-
Save lesleh/fa8289974b65f3d7b9a5bbf55f5028cf to your computer and use it in GitHub Desktop.
Function to auto-curry another function, with strong typing
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
interface Curry { | |
<T1, R>(func: (t1: T1) => R): CurriedFunction1<T1, R>; | |
<T1, T2, R>(func: (t1: T1, t2: T2) => R): CurriedFunction2<T1, T2, R>; | |
<T1, T2, T3, R>(func: (t1: T1, t2: T2, t3: T3) => R): CurriedFunction3< | |
T1, | |
T2, | |
T3, | |
R | |
>; | |
<T1, T2, T3, T4, R>( | |
func: (t1: T1, t2: T2, t3: T3, t4: T4) => R | |
): CurriedFunction4<T1, T2, T3, T4, R>; | |
<T1, T2, T3, T4, T5, R>( | |
func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R | |
): CurriedFunction5<T1, T2, T3, T4, T5, R>; | |
(func: (...args: any[]) => any): (...args: any[]) => any; | |
} | |
interface CurriedFunction1<T1, R> { | |
(): CurriedFunction1<T1, R>; | |
(t1: T1): R; | |
} | |
interface CurriedFunction2<T1, T2, R> { | |
(): CurriedFunction2<T1, T2, R>; | |
(t1: T1): CurriedFunction1<T2, R>; | |
(t1: T1, t2: T2): R; | |
} | |
interface CurriedFunction3<T1, T2, T3, R> { | |
(): CurriedFunction3<T1, T2, T3, R>; | |
(t1: T1): CurriedFunction2<T2, T3, R>; | |
(t1: T1, t2: T2): CurriedFunction1<T3, R>; | |
(t1: T1, t2: T2, t3: T3): R; | |
} | |
interface CurriedFunction4<T1, T2, T3, T4, R> { | |
(): CurriedFunction4<T1, T2, T3, T4, R>; | |
(t1: T1): CurriedFunction3<T2, T3, T4, R>; | |
(t1: T1, t2: T2): CurriedFunction2<T3, T4, R>; | |
(t1: T1, t2: T2, t3: T3): CurriedFunction1<T4, R>; | |
(t1: T1, t2: T2, t3: T3, t4: T4): R; | |
} | |
interface CurriedFunction5<T1, T2, T3, T4, T5, R> { | |
(): CurriedFunction5<T1, T2, T3, T4, T5, R>; | |
(t1: T1): CurriedFunction4<T2, T3, T4, T5, R>; | |
(t1: T1, t2: T2): CurriedFunction3<T3, T4, T5, R>; | |
(t1: T1, t2: T2, t3: T3): CurriedFunction2<T4, T5, R>; | |
(t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction1<T5, R>; | |
(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): R; | |
} | |
const curry: Curry = (fn) => { | |
const arity = fn.length; | |
return function $curry(...args) { | |
if (args.length >= arity) { | |
return fn(...args); | |
} | |
return $curry.bind(null, ...args); | |
}; | |
}; | |
// Example | |
const fn = curry( | |
(a: number, b: number, c: number, d: number, e: number) => a + b + c + d + e | |
) | |
console.log(fn(1)(2, 3, 4, 5)); | |
console.log(fn(1, 2)(3, 4, 5)); | |
console.log(fn(1, 2, 3)(4, 5)); | |
console.log(fn(1, 2, 3, 4, 5)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment