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

TypeScript中类型安全的两个同类型对象差异查找方案

解决TypeScript中对比同类型对象属性差异的类型错误

我需要对比两个同类型的对象,提取出其中一个对象里不存在于另一个对象,或者属性值不同的所有属性。下面的代码能运行,但存在TypeScript类型错误:

export type Thing = {
  name?: string;
  age?: number;
  location?: {
    x: number,
    y: number
  }
};

const things: Thing = { name: "Jim", age: 32, location: {x:1, y:2} };
const things2: Thing = { name: "Jim" };

const things3: Thing = {};

Object.entries(things).forEach(([key, value]) => {
  if (things[key] !== things2[key]) {
    things3[key] = value;
  }
});

对应的错误提示:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Thing'.
No index signature with a parameter of type 'string' was found on type 'Thing'.ts(7053)

我尝试使用ts-extras库的objectEntries方法优化后,错误数量减少:

objectEntries(things).forEach(([key, value]) => {
  if (things[key] !== things2[key]) {
    things3[key] = value;
  }
});

但things3[key] = value;这一行仍存在类型错误:

(parameter) key: keyof Thing
Type 'string | number | { x: number; y: number; } | undefined' is not assignable to type 'undefined'.
Type 'string' is not assignable to type 'undefined'.ts(2322)


解决方案

要解决这个问题,核心是让TypeScript明确当前遍历的key对应的value类型与things3中该属性的类型完全匹配。这里提供两种实用方案:

方案一:精准类型断言

直接在赋值时添加类型断言,让TS确认值的类型与目标属性匹配:

objectEntries(things).forEach(([key, value]) => {
  if (things[key] !== things2[key]) {
    things3[key] = value as Thing[typeof key];
  }
});

方案二:封装泛型对比函数

把对比逻辑封装成可复用的泛型函数,从根源上保证类型安全:

function getObjectDiff<T extends object>(objA: T, objB: T): Partial<T> {
  const diff: Partial<T> = {};
  (Object.keys(objA) as Array<keyof T>).forEach(key => {
    if (objA[key] !== objB[key]) {
      diff[key] = objA[key];
    }
  });
  return diff;
}

// 使用示例
const things3 = getObjectDiff(things, things2);

注意:上述两种方案都是浅对比,如果对象包含嵌套属性(比如示例中的location),直接用!==只能对比引用地址,无法检测嵌套对象内部值的变化。如果需要深对比,需要额外实现递归对比逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:40:34