TypeScript:高阶函数丢弃传入函数的类型信息
对于高阶函数,TypeScript似乎会丢弃有关传入函数的类型信息。例如,以下情况不会引发错误:TypeScript:高阶函数丢弃传入函数的类型信息,typescript,higher-order-functions,Typescript,Higher Order Functions,对于高阶函数,TypeScript似乎会丢弃有关传入函数的类型信息。例如,以下情况不会引发错误: function func (f) { return f(1, 1); } function concat (n: string, m: string) { return n + m; } func(concat) error TS2349: Cannot invoke an expression whose type lacks a call signature. Type
function func (f) {
return f(1, 1);
}
function concat (n: string, m: string) {
return n + m;
}
func(concat)
error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.
当然,如果向高阶函数添加相同的类型信息,则它将捕获错误:
function func (f: (n: string, m: string) => string) {
return f(1, 1);
}
function concat (n: string, m: string) {
return n + m;
}
func(concat)
错误:
error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.
但是,在很多情况下,您可能希望传入具有任意签名的函数,并在稍后在高阶函数中调用该签名时尊重该签名
我已尝试使用类型参数来实现这一点:
function func <F>(f: F) {
return f(1, 1);
}
function concat (n: string, m: string) {
return n + m;
}
func(concat);
有什么方法可以实现我想要实现的吗?我需要一个实际的用例来了解您真正想用这个函数做什么。看起来您应该像这样指定签名:
函数func(f:(n:number,m:number)=>T){
。然后您传入的任何函数都必须与该签名松散匹配。第一个示例的问题是,编译器为函数f
和(f:any)推断并隐式any
类型=>函数func
的任意
。您可以使用noImplicitAny
编译器选项禁用此选项。至于传入具有任意签名的函数,我认为您的意思是说任意返回类型。在这种情况下,@AJRichardson说了什么。谢谢。但我指的是任意返回类型和任意参数类型。您不能根据您的示例使用任意参数类型,因为您将参数(1,1)
传递给函数。因此您需要使用固定参数类型(n:number,m:number)
。您的实际用例是什么?是的,因此在这种情况下,如果传入函数的签名不匹配,我希望使用整数调用f会导致typescript错误。这就是为什么我希望能够保留有关传入函数的类型信息,以便我可以确保有效地调用它n将它作为“回调”传递给的函数进行命名。我需要一个实际的用例来理解您真正想要用这个函数做什么。看起来您应该像这样指定签名:function func(f:(n:number,m:number)=>T):T{
。那么您传入的任何函数都必须松散地匹配该签名。第一个示例的问题是编译器为函数f
和(f:any)推断和隐式any
类型=>函数func
的任意
。您可以使用noImplicitAny
编译器选项禁用此选项。至于传入具有任意签名的函数,我认为您的意思是说任意返回类型。在这种情况下,@AJRichardson说了什么。谢谢。但我指的是任意返回类型和任意参数类型。您不能根据您的示例使用任意参数类型,因为您将参数(1,1)
传递给函数。因此您需要使用固定参数类型(n:number,m:number)
。您的实际用例是什么?是的,因此在这种情况下,如果传入函数的签名不匹配,我希望使用整数调用f会导致typescript错误。这就是为什么我希望能够保留有关传入函数的类型信息,以便我可以确保有效地调用它nside作为“回调”传递给的函数。