Skip to content

Instantly share code, notes, and snippets.

@telekosmos
Created April 15, 2025 06:54
Show Gist options
  • Save telekosmos/e06076ed1fbb46ecd55424fcfe4a664f to your computer and use it in GitHub Desktop.
Save telekosmos/e06076ed1fbb46ecd55424fcfe4a664f to your computer and use it in GitHub Desktop.
TypeScript Curry Function: From Static Types to Variadic Types
// Taken from
// https://dev.to/francescoagati/optimizing-a-typescript-curry-function-from-static-types-to-variadic-types-2ma0
type CurryFunction<T extends unknown[], R> = T extends [infer A, ...infer Rest]
? (arg: A) => CurryFunction<Rest, R>
: R;
function curry<T extends unknown[], R>(
fn: (...args: T) => R
): CurryFunction<T, R> {
return function curried(...args: unknown[]): unknown {
if (args.length >= fn.length) {
return fn(...(args as T));
} else {
return (...args2: unknown[]) =>
curried(...([...args, ...args2] as unknown[]));
}
} as CurryFunction<T, R>;
}
function testCurry() {
const add = (a: number, b: number) => a + b;
const curriedAdd = curry(add);
if (curriedAdd(1)(2) === 3)
console.log("Test curry function with 2 arguments");
const add3Args = (a: number, b: number, c: number) => a + b + c;
const curriedAdd3Args = curry(add3Args);
if (curriedAdd3Args(1)(2)(3) === 6)
console.log("Test curry function with 3 arguments");
const add4Args = (a: number, b: number, c: number, d: number) =>
a + b + c + d;
const curriedAdd4Args = curry(add4Args);
if (curriedAdd4Args(1)(2)(3)(4) === 10) {
console.log("Test curry function with 4 arguments");
}
const curried12 = curriedAdd4Args(1)(2);
if (curried12(3)(4) === 10) {
console.log("Test curry function with partial application");
}
}
testCurry()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment