移除重复构造函数后泛型类表达式报错问题
问题分析:TypeScript构造函数签名重载的兼容规则
先看你的代码:
type Foo<T> = { [S in keyof T]: T[S] } interface IFoo { new <T>(): Foo<T>; new <T>(): Foo<T>; // 移除此行会报错 } const Foo: IFoo = (class {}) const foo = new Foo();
核心原因:重载与单签名的兼容逻辑差异
匿名类的构造函数类型:
class {}的构造函数类型是new () => {},只能构造出空对象实例。单签名的严格检查:当
IFoo只有一个new <T>(): Foo<T>签名时,TypeScript会要求赋值的构造函数必须支持该泛型签名的所有可能场景——也就是不管泛型T被推断成什么类型,构造函数都要能返回对应的Foo<T>(本质就是T本身)。但你的匿名类只能返回空对象,显然做不到这一点,所以编译器触发类型不兼容的报错。多重载的宽松匹配:当
IFoo有两个完全相同的泛型构造签名时,TypeScript的重载匹配逻辑会切换为「只要源构造函数能匹配目标的任意一个重载」即可。此时编译器会尝试匹配:当调用new Foo()时,泛型T会被推断为{},重载签名的返回类型Foo<{}>正好是空对象,和匿名类的返回类型完全一致,因此匹配成功,编译器允许赋值。
简单来说,多重载场景下TypeScript只要求源函数满足某个重载的调用场景;单签名场景下则要求源函数满足该签名的所有可能调用场景,这就是多一行重复签名就不报错的关键原因。
内容的提问来源于stack exchange,提问作者Matthieu Riegler
相关产品推荐
相关产品推荐

