如果使用`keyof`是一个泛型函数,为什么不能打字参数的类型?

时间:2018-01-07 04:48:53

标签: typescript

为什么这会出错?

lbImg.src = galImg.slice(4, -1).replace(/"/g, "");

但这并不是:

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');

请注意,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');

中缺少<K extends keyof MyType>

1 个答案:

答案 0 :(得分:2)

应该注意的是,第一个示例在禁用strictFunctionTypes时进行类型检查。这会禁用函数类型的双变量参数检查。如果没有此检查,编译器将允许在运行时可能不健全的代码。

可以找到一个很好的解释here

  

...一个更具体类型接受函数是否应该被赋予接受一个特定于较少类型的函数的问题提供了一个先决条件的答案,该函数是否应该将一个更具体类型的数组赋值给一个数组不太具体的类型。如果后者不是这种情况,在绝大多数情况下都不会是一个可接受的类型系统,因此我们必须对函数参数类型的特定情况进行正确的权衡。

通过使myFunction具体的类型参数具体化来解决第二个示例中的问题:keyof MyType在编译时解析为string,这意味着myFunction的类型签名实际上是myFunction(key: string): string

以下示例通过相反的方式进行类型检查 - 它使canInfer上的类型约束更不宽容(playground link):

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'));