简体   繁体   English

如果打字稿是使用`keyof`的泛型函数,为什么打字稿不能推断出它的类型?

[英]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.

相关问题 TypeScript:推断通用 keyof 的类型 - TypeScript: Infer type of generic keyof 声明构造函数以从TypeScript中的(keyof)参数正确推断泛型 - Declare a constructor to correctly infer generic type from (keyof) argument in TypeScript 为什么 Typescript 不能推断嵌套泛型函数的类型? - Why can't Typescript infer the type of a nested generic function? 在 TypeScript 中,如何推断我的参数并强加约束,即所有项都是 T 的键,其中 T 是函数的泛型类型? - In TypeScript, how can I infer my arguments and impose a constraint that all items be keyof T, where T is the generic type for the function? 为什么TypeScript在嵌套对象中不能推断泛型类型? - Why can't TypeScript infer a generic type when it is in a nested object? 为什么带有类型联合类型参数的泛型 TypeScript 函数不能推断出与返回类型相同的类型? - Why cannot a generic TypeScript function with an argument of type from a type union infer the same type as the return type? 为什么Typescript不能推断出这个函数的参数类型? - Why can't Typescript infer the argument types of this function? 为什么 Typescript 不能推断出可选 arguments 的 function 参数类型? - Why can't Typescript infer function argument types for optional arguments? 为什么 typescript 不能正确推断 T[K]<t extends person, k keyof t> 通用的?</t> - Why typescript does not properly infer T[K] with <T extends Person, K extends keyof T> generic? 如何让 TypeScript 通用 function 类型参数是 object 的键值的返回类型 - How to have TypeScript generic function with type argument being keyof an object have return type of that object's key's value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM