export interface Curried { (a: A): (b: B) => T; (a: A, b: B): T; } export function curry2(fn: (a: A, b: B) => T): Curried { function curried(a: A): (b: B) => T; function curried(a: A, b: B): T; function curried(a: A, ...b: [] | [B]): T | ((b: B) => T) { if (b.length === 0) { return b => fn(a, b); } else { return fn(a, ...b); } } return curried; }