如何 Package 函数而不更改其在Typescript中的泛型类型?
function x() {
console.log('Original Function');
}
function wrapper<T extends Function>(func: T): T {
// Typescript compiler error:
// Type '() => void' is not assignable to type 'T'.
return () => {
console.log('Wrapped Function');
func.call(null);
}
}
const xWrapped = wrapper(x);
xWrapped(); // logged 'Wrapped Function' & 'Original Function'
4条答案
按热度按时间zazmityj1#
这里有一个替代方法,它保留内部函数的参数并返回类型,而不依赖于变量类型。
当用
x
调用wrapper
时,TS编译器将其类型推断为function wrapper<[string], void>(operation: (operationParameters_0: string) => void, parameters_0: string): void
。如果尝试调用
wrapper(x, 123)
,它会失败,并具有漂亮的类型安全:Argument of type '123' is not assignable to parameter of type 'string'.
oyt4ldly2#
Package 函数应该接受一个函数,并返回一个类型签名完全相同的函数。
Typescript无法知道传递的函数接受了多少参数或返回了什么,您的函数隐式假定它接受了0个参数(除了这个)并返回void。
目前还没有一个很好的方法来保存函数签名。不过,在以后的版本中有一个新的建议可以解决这个问题:https://github.com/Microsoft/TypeScript/issues/5453
现在,您可以创建一个如下所示的通用 Package 器。
使用Variadic类型的建议,此函数可以写成以下形式
注意这里的主要区别是没有强制类型转换,上面的解决方案必须告诉编译器返回变量和输入变量是同一类型。然而,对于variadic类型,参数本身可以通用类型化。(注意variadic类型目前不在typescript中,当它被包括在内时,上面的代码完全有可能有语法错误)
针对TypeScript 4.3版本的更新: Package 器的已实现提案工作代码将如下所示
可以在这里找到一些简短但有帮助的关于Variadic元组用法的信息和示例:是的。
ccrfmcuu3#
我更喜欢一个更简单的解决方案,就像贝娄:
输出量
或者,如果您想要更一般的内容:
输出量
eqfvzcg84#
下面是我发现的另一种方法,它甚至保留了 Package 函数的泛型: