在本例中,我使用参数类型(keyof TFoo)[]
来预期包含TFoo
中的任何键的数组,为了使示例简单,但是我在任何时候使用模式<T, TSomeClass extends SomeClass<T>>
时都看到了类型参数的推断的相同行为。它似乎正确地推断了类型TFoo
,因为它适用于第一个fooBarBad
函数参数bar
的类,所以在这个例子中,它将TBar
标识为Bar<{ a: number, b: number }>
,但是对于第二个参数fooKeys
,它将TFoo
推断为{ a: any, c: any }
,这是从数组中传递的值中获得的。但我至少希望它对两个函数参数应用相同的TFoo
推断值,因为它们都引用相同的类型参数TFoo
。
class Bar<TFoo> {
constructor(foo: TFoo) {}
}
function fooBarBad<TFoo, TBar extends Bar<TFoo>>(bar: TBar, fooKeys: (keyof TFoo)[]) {}
// No error, but I expect one - fooKeys is instead inferred to be ('a' | 'c')[]
fooBarBad(new Bar({ a: 1, b: 2 }), ['a', 'c']);
有没有别的方法可以声明这个来得到我想要的推论?或者有什么技巧来强迫它?
一个更简单的例子就能得出我所期望的结论。
function fooBar<TFoo>(foo: TFoo, fooKeys: (keyof TFoo)[]) {}
// Error as expected - 'c' is not a key of TFoo
fooBar({ a: 1, b: 2 }, ['a', 'c']);
1条答案
按热度按时间b4lqfgs41#
TypeScript在查找推理目标时会确定参数的优先级。
TBar
的类型由第一个参数推理,而TFoo
由第二个参数推理,* 而不是 * 通过TFoo
的约束推理。我们可以简化您的示例,只使用一个泛型参数
TFoo
。从而得出正确的推论。
Playground