TypeScript给泛型添加交叉类型后出现id属性不兼容报错是什么原因?
问题原因分析
- 初始版本无报错的核心原因是
Foo<T>为纯同态映射类型Partial<T>是TS内置的同态映射类型,仅会遍历处理传入泛型T自身的属性。对于T extends Partial<T>这种递归约束,TS有专门的兼容逻辑:任意类型的属性都必然是自身可选版本的子类型,因此会直接判定约束成立,不需要额外逐属性校验。 - 新增交叉类型后报错的原因
当你把Foo<T>修改为Partial<T> & {x?: string}后,Foo<T>不再是纯同态映射类型,TS会关闭上述特殊兼容逻辑,对递归约束执行严格的逐属性校验。
此时泛型参数T是无约束的,TS无法预判T是否会包含和ID冲突的属性定义,在推导T & ID的id属性和Foo<T & ID>中id属性的兼容性时出现推导异常,才抛出了看起来和新增的x属性无关的id类型错误。
解决方案
要避免这个问题,只需要把额外的属性合并到Partial的入参中,让Foo<T>保持为纯同态映射类型即可:
type Foo<T> = Partial<T & { x?: string; }>;
修改后TS会恢复对同态映射类型的递归约束兼容逻辑,报错就会消失。
内容的提问来源于stack exchange,提问作者user3612643
相关产品推荐
相关产品推荐

