How to solve the problem of ts type labeling of curry functions?

38 Views Asked by At
/**
 * @type T Represents the type of the incoming function
 * @type First Represents the parameters entered for the first time
 */
type CurryFunc<T, First extends any[]> = T extends (
  ...args: infer Args
) => infer R
  ? // eslint-disable-next-line @typescript-eslint/no-unused-vars
    Args extends [...First, infer Mid, ...infer Tail]
    ? (v: Mid) => CurryFunc<T, [...First, Mid]>
    : R
  : T;

/**
 * Corialization function.  It can be deduced automatically according to the type of incoming function.
 * @param fn Functions that need to be Corey
 * @param rest The initial parameters of a function that needs to be Corialized
 * @returns Returns the return value of a new function that is Corialized or a function that needs to be Corialized
 * @example
 *  function add(a: number, b: number, c: number, d: number, e: number) {
 *    return a + b + c;
 *  }
 *  curry(add)(1)(2)(3)(4)(5);
 *  curry(add, 1)(2)(3)(4)(5);
 *  curry(add, 1, 2)(3)(4)(5);
 *  curry(add, 1, 2, 3)(4)(5);
 *  curry(add, 1, 2, 3, 4)(5);
 *  curry(add, 1, 2, 3, 4, 5);
 */

export function curry<T extends (...args: any[]) => any, First extends any[]>(
  fn: T,
  ...rest: First
): CurryFunc<T, First> {
  return function (...args: any[]): any {
    const currentArgs = [...rest, ...args];
    return currentArgs.length >= fn.length
      ? fn(...currentArgs)
      : curry(fn, ...currentArgs);
  } as CurryFunc<T, First>;
}

function add(a: number, b: number, c: number, d: number, e: number) {
  return a + b + c;
}
curry(add)(1)(2)(3)(4)(5);
curry(add, 1)(2)(3)(4)(5);
curry(add, 1, 2)(3)(4)(5);
curry(add, 1, 2, 3)(4)(5);
curry(add, 1, 2, 3, 4)(5);
curry(add, 1, 2, 3, 4, 5);
// @ts-ignore
curry(add, 1,2)(3,4)(5);

This is my implementation of type tagging of my curry function, which can not solve the error problem of curry (add, 1,2) (3,4)(5); . What do I need to do in order to solve the problem of indefinite parameter transmission? I want to solve the problem that multiple parameters can be passed in the second or multiple calls, with automatic type prompts.

0

There are 0 best solutions below