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

如何用TypeScript类型检查多个Partial对象是否构成完整Interface

TypeScript 多对象合并后验证目标接口属性的实现

实现思路

  • 先实现双对象合并类型:处理两个对象的属性覆盖逻辑,后传入的对象会覆盖先传入对象的同名属性。
  • 再实现元组递归合并类型:遍历所有传入的参数对象,递归合并成一个最终的对象类型。
  • 最后实现验证逻辑:检查合并后的最终类型是否包含目标接口的所有属性,仅允许符合条件的参数列表通过类型检查。

完整代码示例

interface Box {
  height: number;
  width: number;
  length: number;
  weight: number;
}

// 合并两个对象,后面对象覆盖前面对象的同名属性
type Merge<O1, O2> = Omit<O1, keyof O2> & O2;

// 递归合并元组中的所有对象,得到最终合并类型
type MergeTuple<T extends any[]> = T extends [infer First, ...infer Rest]
  ? Merge<First, MergeTuple<Rest>>
  : {};

// 验证参数列表合并后是否满足目标接口,返回合法元组或触发类型错误
type Check<T extends any[], I> = MergeTuple<T> extends I ? T : never;

function createBox<T extends any[]>(...args: Check<T, Box>): Box {
  return Object.assign({}, ...args);
}

// 测试用例
// ❌ 错误:缺少weight属性,TypeScript会提示类型不匹配
createBox({ height: 11, width: 15 }, { length: 24 });

// ✅ 正确:width被后续参数覆盖,合并后包含Box的所有属性
createBox({ height: 11, width: 15 }, { length: 24, width: 3, weight: 5 });

代码细节解释

  1. Merge 类型
    使用Omit<O1, keyof O2>移除第一个对象中与第二个对象重复的属性,再通过交叉类型& O2合并第二个对象的属性,确保后传入的对象属性能覆盖前面的。

  2. MergeTuple 类型
    借助递归条件类型遍历参数元组的每一个元素,依次调用Merge完成全量合并。如果元组为空,则返回空对象{}作为初始值。

  3. Check 类型
    检查合并后的类型MergeTuple<T>是否是目标接口I的子类型(即包含I的所有必填属性)。如果满足条件,返回原参数元组T;否则返回never,触发TypeScript的类型错误提示。

  4. createBox 函数
    接收任意数量的对象参数,通过Check类型做前置验证,最终用Object.assign合并所有参数并返回符合Box接口的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:15:01