【发布时间】:2021-01-06 04:22:32
【问题描述】:
试图创建一个类型安全的柯里化函数。我在 SO 上看到的所有答案都建议函数重载,我不想这样做。
我遇到了type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
它确实给出了函数的所有参数类型,并且可以通过索引选择参数类型。但是,如何对 ArgumentTypes 进行切片以仅具有正确数量的参数及其类型?
在下面的示例中 curried(1, 1); 给出错误“预期 3 个参数,但得到 2 个”。
function curry<T extends Function>(fn: T) {
const fnArgs: readonly string[] = args(fn);
const cachedArgs: readonly any[] = [];
type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
type FnArguments = ArgumentTypes<typeof fn>;
function curryReducer(...args: FnArguments) {
cachedArgs.push(...args);
return cachedArgs.length >= fnArgs.length
? fn(...cachedArgs)
: curryReducer;
}
return curryReducer;
}
function args<T extends Function>(fn: T): readonly string[] {
const match = fn
.toString()
.replace(/[\r\n\s]+/g, ' ')
.match(/(?:function\s*\w*)?\s*(?:\((.*?)\)|([^\s]+))/);
return match
? match
.slice(1, 3)
.join('')
.split(/\s*,\s*/)
: [];
}
function adding(a: number, b: number, c: number) {
return a + b + c;
}
const curried = curry(adding);
const add2 = curried(1, 1);
```;
【问题讨论】:
标签: typescript