如何在TypeScript中扩展类型并覆盖指定属性类型?
解决TypeScript中扩展类型并覆盖指定属性类型的问题
这个场景我碰到好多次了!你用AB & {A: number}没效果的原因是交叉类型会对冲突属性的类型取交集——string & number的结果是never,这显然不是你想要的覆盖效果。
正确的做法:用Omit工具类型剔除旧属性,再合并新类型
TypeScript内置的Omit工具类型可以帮你先移除原类型中需要修改的属性,再和新的属性定义合并,完美实现“继承+覆盖”的需求:
// 原类型 type AB = { A: string; B: string; }; // 先剔除AB中的'A'属性,再合并新的'A: number'定义 type Final = Omit<AB, 'A'> & { A: number; };
现在Final的类型就是你想要的:{ A: number; B: string; }。
验证效果
我们可以写个例子测试一下:
// 合法:符合Final类型定义 const validObj: Final = { A: 42, B: "foo" }; // 报错:A的类型必须是number,不能是string const invalidObj: Final = { A: "42", B: "foo" };
备选方案:用Pick手动保留需要的属性
如果原类型的属性很少,你也可以用Pick直接保留不需要修改的属性,再合并新属性:
type Final = Pick<AB, 'B'> & { A: number; };
不过当原类型有大量属性时,Omit显然更高效——只需要指定要修改的那个属性就行,不用逐个列举保留的属性。
为什么交叉类型不行?
再补充说下你最初尝试的问题:交叉类型AB & {A: number}会把A的类型计算为string & number,这两个类型没有重叠的部分,所以结果是never。也就是说你的Final类型实际上是{ A: never; B: string; },自然达不到你想要的效果。
内容的提问来源于stack exchange,提问作者Dakito
相关产品推荐
相关产品推荐

