Skip to content

柯里化 1

题目

在此挑战中建议使用 TypeScript 4.0

柯里化 是一种将带有多个参数的函数转换为每个带有一个参数的函数序列的技术。

例如:

ts
const add = (a: number, b: number) => a + b;
const three = add(1, 2);

const curriedAdd = Currying(add);
const five = curriedAdd(2)(3);

传递给 Currying 的函数可能有多个参数,您需要正确输入它的类型。

在此挑战中,柯里化后的函数每次仅接受一个参数。接受完所有参数后,它应返回其结果。

精选

This solution is longer but slightly better than the canonical one (#1404) in that it takes care to preserve the names of the function parameters. Extracting the first element of a tuple while preserving its label is tricky but possible thanks to @jcalz's answer to a Stack Overflow question.

ts
// See https://stackoverflow.com/a/72244704/388951
type FirstAsTuple<T extends any[]> = T extends [any, ...infer R]
  ? T extends [...infer F, ...R]
    ? F
    : never
  : never;

type Curried<F> = F extends (...args: infer Args) => infer Return
  ? Args["length"] extends 0 | 1
    ? F
    : Args extends [any, ...infer Rest]
    ? (...args: FirstAsTuple<Args>) => Curried<(...rest: Rest) => Return>
    : never
  : never;

declare function Currying<T extends Function>(fn: T): Curried<T>;

Compare: image

vs: Screenshot 2023-07-05 at 3 00 48 PM

Released under the MIT License.