Skip to content

Instantly share code, notes, and snippets.

@gutchom
Created September 10, 2025 19:55
Show Gist options
  • Select an option

  • Save gutchom/58eff8b0a1a7552fbb13393ded55af00 to your computer and use it in GitHub Desktop.

Select an option

Save gutchom/58eff8b0a1a7552fbb13393ded55af00 to your computer and use it in GitHub Desktop.
A type safe curry function
type Curry = <A extends unknown[], R>(
fn: (...arg: readonly [...A]) => R,
) => Curried<A, R>;
type Curried<A extends unknown[], R> = <T extends unknown[]>(
...arg: readonly [...T]
) => T extends A ? R : A extends [...T, ...infer U] ? Curried<U, R> : never;
const curry: Curry =
<A extends unknown[], R>(fn: (...arg: readonly [...A]) => R): Curried<A, R> =>
<T extends unknown[]>(
...args: readonly [...T]
): T extends A ? R : A extends [...T, ...infer U] ? Curried<U, R> : never =>
fn.length <= args.length
? fn.apply(this, args)
: curry(fn).bind(this, ...args);
function add(x: number, y: number, z: number): number {
return x + y + z;
}
var a = curry(add);
var b = a(1, 2);
var c = b(3);
console.log(c);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment