泛型类实例化时类型参数推断忽略泛型约束的疑问
问题解答
这不是Bug,是TypeScript的有意设计。
原因分析
当你用new MyClass({a:1})自动推断类型时,TypeScript会根据构造函数传入的参数,把泛型T推断为最具体的类型——也就是{a: number}(这个类型确实满足T extends MyType的约束)。而method方法要求的参数类型就是这个缩小后的{a: number},传入{b:1}自然会报错,因为后者没有a属性,不符合推断出的T类型。
而手动指定MyType时,T被设定为包含可选a和b的类型,{b:1}完全符合这个类型定义,所以可以正常调用。
如何阻止泛型类的类型推断
有几种可行的方式:
使用
NoInfer工具类型(TS 5.1+)
修改构造函数参数类型,让TypeScript不从构造函数参数推断T,而是使用默认的MyType:type MyType = { a?: number, b?: number }; import { NoInfer } from 'typescript'; class MyClass<T extends MyType = MyType> { constructor(t: NoInfer<T>) {} method(t: T) {} } const myClass2 = new MyClass({ a: 1 }); myClass2.method({ b: 1 }); // 不再报错固定构造函数参数类型为约束类型
把构造函数的参数类型直接设为MyType,而非泛型T,这样自动推断时会直接使用默认的MyType:type MyType = { a?: number, b?: number }; class MyClass<T extends MyType = MyType> { constructor(t: MyType) {} method(t: T) {} } const myClass2 = new MyClass({ a: 1 }); myClass2.method({ b: 1 }); // 不再报错显式指定泛型类型
就像示例中的myClass1一样,手动指定<MyType>,直接跳过自动推断逻辑。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

