[英]Why can't typescript infer an argument's type if it is a generic function using `keyof`?
Why does this yeild an error? 为什么会产生错误?
type MyType = {
a: string, b: string
}
function cantInfer<In, Out>(fn: (i: In) => Out, i: In) {
}
function myFunction<K extends keyof MyType>(key: K): string {
return '';
}
cantInfer(myFunction, 'a');
But this doesn't: 但这不是:
type MyType = {
a: string, b: string
}
function cantInfer<In, Out>(fn: (i: In) => Out, i: In) {
}
function myFunction(key: keyof MyType): string {
return '';
}
cantInfer(myFunction, 'a');
Note, the missing <K extends keyof MyType>
in myFunction
请注意, myFunction
缺少<K extends keyof MyType>
It should be noted that your first example does type-check when strictFunctionTypes
is disabled. 应该注意的是,当禁用strictFunctionTypes
时,您的第一个示例会进行类型检查。 This disables bivariant parameter checking for function types. 这将禁用函数类型的双变量参数检查。 Without this check, the compiler allows code that may be unsound at runtime. 没有此检查,编译器将允许在运行时不正确的代码。
A good explanation can be found here : 一个很好的解释可以在这里找到:
... the question of whether a more-specific-type-accepting function should be assignable to a function accepting a less-specific type provides a prerequisite answer to whether an array of that more specific type should be assignable to an array of a less specific type. ...是否应将更具体类型的函数分配给接受较不具体类型的函数,这一问题为是否应将更具体类型的数组分配给较小具体类型的数组提供了先决条件具体类型。 Having the latter not be the case would not be an acceptable type system in the vast majority of cases, so we have to take a correctness trade-off for the specific case of function argument types. 在大多数情况下,没有后者的情况将不是可接受的类型系统,因此我们必须对函数参数类型的特定情况进行正确性的权衡。
You fix the issue in your second example by making the type parameters for myFunction
concrete: keyof MyType
resolves to string
at compile time, meaning the type signature for myFunction
is effectively myFunction(key: string): string
通过将myFunction
的类型参数具体化来解决第二个示例中的问题: keyof MyType
在编译时解析为string
,这意味着myFunction
的类型签名实际上是myFunction(key: string): string
The following example type-checks by doing the opposite—It makes the type constraints on canInfer
less permissive ( playground link ): 下面的示例通过相反的方式进行类型检查—它使canInfer
的类型约束不太宽松( 游乐场链接 ):
type MyType = {
a: string, b: string
}
function canInfer<In extends keyof MyType, Out>(fn: (i: In) => Out, i: In) {
return fn(i);
}
function myFunction<K extends keyof MyType>(key: K): string {
let myType = {
a: "foo",
b: "bar"
}
return myType[key];
}
alert(canInfer(myFunction, 'a'));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.