包装函数应接收一个函数并返回一个完全相同类型签名的函数。
Typescript 无法知道传递的函数需要多少个参数或它返回什么,并且您的函数隐式假设它需要 0 个参数(除了 this)并返回 void。
目前没有一种很好的方法可以在打字稿中保存函数签名。但是,对于以后的版本有一个新的提议可以解决这个问题:https ://github.com/Microsoft/TypeScript/issues/5453
现在,您可以制作一个看起来像这样的通用包装器。
function wrapper<T extends (...args:any[])=>any>(func: T): T {
return <T>((...args:any[]) => {
console.log('Wrapped Function');
return func(...args);
});
}
有了可变参数类型的提议,这个函数可以写成这样
function wrapper<...TArgs,TRet>(func:(...args:...TARGS)=>TRet) {
return (...args:...TARGS) => {
console.log("Wrapped function");
return func(...args);
}
}
注意这里的主要区别是上面的解决方案没有强制转换必须告诉编译器返回变量与输入变量的类型相同。然而,对于可变参数类型,参数本身可以被一般地输入。(请注意,可变参数类型当前不在打字稿中,当确实包含在内时,上述代码完全有可能存在语法错误)
TypeScript 4.3 版本更新:已
实现提案的包装器工作代码将如下所示
type InferArgs<T> = T extends (...t: [...infer Arg]) => any ? Arg : never;
type InferReturn<T> = T extends (...t: [...infer Arg]) => infer Res ? Res : never;
function getWrapper<TFunc extends (...args: any[]) => any>(func: TFunc)
: (...args: InferArguments<TFunc>) => InferReturn<TFunc> {
return (...args: InferArguments<TFunc>) => {
// something before
try {
return func(...args);
} finally {
// something after;
}
};
}
可以在此处找到有关使用可变元组的一些简短但有用的信息和示例: https ://fettblog.eu/variadic-tuple-types-preview/ 。