实现一个 Curry 工具类型,用来实现函数类型的柯里化处理。具体的使用示例如下所示:
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = // 你的实现代码
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
最开始我写的是
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [...infer A, infer B]
? A extends []
? F
: Curry<(...args: A) => (args: B) => R>
: F
这样可以实现基本功能,但是有一个缺点,就是无法保留原始的参数名 那么要想保留原始的参数名,就需要将B转为一个数组,即下面的LastAsArray,这样最终参数名得以保留
type LastAsArray<T extends any[]> = T extends [infer A, ...infer B] ? B extends [] ? T : LastAsArray<B> : T;
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [...infer A, infer B]
? A extends []
? F
: Curry<(...args: A) => (...args: LastAsArray<P>) => R>
: F
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (a: number) => (b: string) => Date