You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型接口扩展通用解法:TypeScript接口类型合并需求

泛型实现TypeScript接口合并与merge函数

刚好碰到过类似的需求,咱们一步步来解决这个问题:你有两个接口A和B,想要实现一种泛型方案,让合并后的类型效果等同于interface D——也就是后面的类型(B)会覆盖前面类型(A)的同名属性,同时把两个类型的所有非同名属性都整合进来,还要写一个merge函数来实现对象的合并并返回对应的合并类型。

第一步:定义合并类型Merge<T, U>

TypeScript原生的交叉类型T & U虽然能合并属性,但如果有同名属性会变成never,不符合咱们的需求。所以咱们需要先把前面类型T中与U重复的属性去掉,再和U交叉,这样U的属性就能完全覆盖T的同名属性了。

// 核心合并类型:U的属性会覆盖T的同名属性,同时保留双方独有属性
type Merge<T, U> = Omit<T, keyof U> & U;

简单解释下:

  • Omit<T, keyof U>:从T中移除所有在U里存在的属性键,只保留T独有的属性
  • & U:把处理后的T和完整的U做交叉,这样U的属性会完全保留,同时整合T的独有属性

第二步:实现merge函数

有了合并类型,咱们就可以写对应的合并函数了,用对象扩展运算符就能实现浅合并(刚好匹配你示例里的需求,sub对象会直接被覆盖):

function merge<T, U>(t: T, u: U): Merge<T, U> {
  // 用扩展运算符实现对象浅合并,u的属性会覆盖t的同名属性
  return { ...t, ...u } as Merge<T, U>;
}

这里用as Merge<T, U>做类型断言,是因为TypeScript有时候没法自动推导扩展运算符后的精确类型,手动断言能让类型更准确。

验证效果

咱们把你的示例代码放进来测试,看看是不是完全符合预期:

// 原接口A
interface A { 
  name: string; 
  value: number; 
  sub: { query: number[] };
  old: number; 
}

// 原接口B
interface B { 
  name: string; 
  value: string; 
  sub: { query: string[] };
  new: boolean; 
}

// 期望的目标接口D
interface D { 
  name: string; 
  value: string; 
  sub: { query: string[] };
  old: number; 
  new: boolean; 
}

// 验证Merge<A, B>是否等于D
type C = Merge<A, B>;
// 此时C的类型完全等同于D,可以通过类型检查确认:
const test: C = {
  name: "test",
  value: "string", // 类型为string,说明B的属性覆盖了A的number类型
  sub: { query: ["1", "2"] }, // query为string[],正确覆盖
  old: 123,
  new: true
};

// 测试merge函数
const a: A = { name: "a", value: 123, sub: { query: [1,2] }, old: 456 };
const b: B = { name: "b", value: "hello", sub: { query: ["x","y"] }, new: false };
const merged = merge(a, b);
// merged的类型是Merge<A,B>,也就是D的类型,所有属性都符合预期
console.log(merged.value); // 类型为string,值为"hello"
console.log(merged.sub.query); // 类型为string[],值为["x","y"]

这样就完全实现了你想要的效果:合并后的类型保留了B的同名属性,同时整合了A的独有属性old和B的独有属性new。

内容的提问来源于stack exchange,提问作者Viatorus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:47:09