TypeScript接口扩展泛型P时子类型约束不匹配如何解决?
问题原因
你猜测的原因是正确的:虽然P声明了extends _ItemFundamentI<T>,但TypeScript允许P作为子类型收窄_ItemFundamentI的属性类型,比如P可以将__typename__定义为比typeof ITEM_TYPENAME更窄的字面量类型,此时ItemI同时继承P和_ItemFundamentI<T>就会出现同名字段类型冲突,所以触发了该报错。接口的readonly修饰符仅限制实例修改属性,不会阻止类型层面的子类型收窄,因此不影响该报错逻辑。
解决方案
- 方案1:移除重复继承(最推荐)
因为P本身已经满足_ItemFundamentI<T>的约束,自带所有基础属性,不需要再让ItemI重复继承_ItemFundamentI<T>,修改后代码如下:
export interface ItemI<T, P extends _ItemFundamentI<T>> extends P { // 此处可添加ItemI专属的额外属性 }
- 方案2:用交叉类型替代接口继承
如果你需要显式保证ItemI一定包含_ItemFundamentI<T>的所有属性,可以用交叉类型实现,TS会自动处理类型兼容:
export type ItemI<T, P extends _ItemFundamentI<T>> = P & _ItemFundamentI<T>
- 方案3:强制保护基础属性不被覆盖
如果要彻底避免P中的属性覆盖_ItemFundamentI的基础属性,可以先把P里的基础属性过滤掉再合并,这样基础属性的类型永远以基础接口为准:
export type ItemI<T, P extends _ItemFundamentI<T>> = Omit<P, keyof _ItemFundamentI<T>> & _ItemFundamentI<T>
内容的提问来源于stack exchange,提问作者lmonninger
相关产品推荐
相关产品推荐

