Skip to content

Instantly share code, notes, and snippets.

@MikuroXina
Last active July 11, 2022 02:35
Show Gist options
  • Save MikuroXina/8bdeb8215185022ec67c89df2083b0fe to your computer and use it in GitHub Desktop.
Save MikuroXina/8bdeb8215185022ec67c89df2083b0fe to your computer and use it in GitHub Desktop.
Currying manipulation for N-ary function.
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
type Curried<F> = F extends (...args: infer A) => infer R
? Equal<F, () => R> extends true
? () => R
: (A extends [infer F, ...infer S]
? (arg: F) => Curried<(...rest: S) => R>
: R
)
: never;
function curry<F extends (...args: any[]) => unknown>(fn: F): Curried<F> {
if (fn.length === 0) {
return (() => fn()) as Curried<F>;
}
const curried = (fn: F, ...argStack: unknown[]) => (newArg: unknown) => {
const totalArgs = [...argStack, newArg];
if (fn.length <= totalArgs.length) {
return fn(...totalArgs);
}
return curried(fn, ...totalArgs);
};
return curried(fn) as Curried<F>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment