• curry a function fn, with optional thisArg option for binding as the this-object.
    what is currying? it allows a multi-parameter function to be transformed into a higher order function that always takes one argument, and spits out another function which also take only one argument, and so on... until all parameters have been filled, upon which the final function finally evaluates into the return value (type parameter R in this case).

    note that this function relies on fn.length property to identify the number of required arguments taken by fn. this means that default valued arguments (such as c in fn: (a: number, b: number, c = 5) => number), or rest/spread arguments (such as args in fn: (a: number, b: number, ...args: number[]) => number), are not considered as required, and thus do not increment the count of fn.length.

    currying is usually implemented terribly through the use of closure. example: ((arg0) => (arg1) => (arg2) => fn(arg1, arg2, arg3))()
    this is bad because when you evaluate a curry with N-parameters, you also have to make N-calls (albeit it being tail-calls), instead of just one call should you have had all the parameters from the beginning. not to mention that all javascript engines famously do not perform tail-call optimizations.
    but here, I've implemented currying using the bind method, which means that once all parameters are filled, the function goes through only one call (no overheads).
    the same example from before would translate into: fn.bind(thisArg, arg0).bind(thisArg, arg1).bind(thisArg, arg2)() when binding is used

    Type Parameters

    • FN extends ((...args) => any)
    • R extends any = ReturnType<FN>
    • ARGS extends any = Parameters<FN>

    Parameters

    • fn: FN

      the function to curry

    • Optional thisArg: ThisParameterType<FN>

      provide an optional argument to use as the this object inside of fn

    Returns CurrySignature<FN, R, ARGS>

    a series of single argument partial functions that does not evaluate until all parameters have been provided

    Example

    const abcd = (a: number, b: string, c: boolean, d: symbol): string => (String(a) + b + String(c) + String(d))
    const abcd_curry = curry(abcd) // type: (arg: number) => (arg: string) => (arg: boolean) => (arg: symbol) => string
    console.log(
    abcd_curry(42) // type: (arg: string) => (arg: boolean) => (arg: symbol) => string
    (" hello to za warudo! ") // type: (arg: boolean) => (arg: symbol) => string
    (true) // type: (arg: symbol) => string
    (Symbol.iterator) // return type: string
    ) // logs `"42 hello to za warudo! true Symbol(Symbol.iterator)"`

Generated using TypeDoc