具有多个类型参数的泛型中的推断类型

Inferred type in generic with multiple type parameters

我正在尝试设置一个泛型,其中参数是另一个对象的键。当两种类型都是函数的参数时,我可以使用 extends keyof 来完成此操作。

然而,当提供键列表的类型不是参数,只是泛型类型时,打字稿需要设置两种泛型类型。

考虑以下代码:

interface Bar {
  z: string;
  t: number;
}

declare function foo1<T extends keyof Bar>(x: T)
let t1 = foo1('z');

declare function foo2<K, T extends keyof K>(x: T)
let t2 = foo2<Bar>('t');

declare function foo3<T>(x: T)
let t3 = foo3<keyof Bar>('t');

Playground link

函数 foo2 失败,因为未指定第二种类型 T。但是我觉得 TS 应该能够在没有明确的第二种类型的情况下推断出正确的类型。

foo3 是我的解决方法,但不太好用,是否可以让 typescript 执行此推理,或者这是向 TS 团队提出的功能请求/错误报告?

Microsoft/TypeScript#14400. For now, you can't do that. Instead, I will give you a workaround that I often suggest in cases like this: curried 函数中已经有关于类型参数的部分推断(不使用默认值)的优秀建议。

declare function curriedFoo<B>(): <T extends keyof B>(x: T)=>any;
let t4 = curriedFoo<Bar>()('t'); // okay

无参数函数 curriedFoo() 采用类型参数 B(我不能将 K 用于除了键以外的任何东西,抱歉),并且 returns一个你真正想要的类型的函数,缩小到只接受一个 T extends keyof B 参数(这是我想使用 K 的地方,但没关系)。

它有点笨拙,但它完成了工作。希望有所帮助;祝你好运!

您与 foo2 关系密切。这是让它工作的应该是什么。

declare function foo2<T, K = keyof T>(x: K)
let t2 = foo2<Bar>('t');

您可以将一个泛型类型参数分配给一个类型(在本例中为 T 的类型),而不是期待一个新的泛型类型参数。

也可以直接将参数类型分配给 keyof 给定的通用类型 T

declare function foo4<T>(x: keyof T);
let t4 = foo4<Bar>('t');