例如,假设我正在编写一个备忘函数,该函数接受一个函数并返回另一个函数。我想利用TypeScript,以便即使我事先不知道输入函数的类型,也可以确保输出函数具有与输入函数相同的类型。这是一些示例代码:
function wrap(fn) {
return function(...args) {
return fn(...args);
};
}
function repeat1(a: string, b: number): string {
return a.repeat(b);
}
const repeat2 = wrap(repeat1);
不幸的是,repeat2
解析为类型(...args: any[]) => any
。我似乎找不到一种将输入类型传播到输出类型的方式来表达wrap
函数的方法。
答案 0 :(得分:1)
您需要使用泛型和Tuples in rest parameters and spread expressions
function wrap<A extends any[], R>(fn: (...a: A) => R) {
return function(...args: A) {
return fn(...args);
};
}
function repeat1(a: string, b: number): string {
return a.repeat(b);
}
const repeat2 = wrap(repeat1); // inferred to const repeat2: (a: string, b: number) => string
以上版本不适用于通用功能。如果我们放弃任何实现类型的安全性,我们可以创建一个保留通用函数参数的版本(这是可以接受的折衷方案,因为我们可以获得更好的呼叫站点安全性,这一点更为重要)
function wrap<T extends Function>(fn: T): T {
return function(...args: any[]) :any {
return fn(...args);
} as any;
}
wrap(<T>(x: T): T => x)