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

如何在TypeScript中实现对象差异提取并精确推导返回类型

实现精确类型推导的对象差异字段提取函数

问题描述

需要写一个函数,提取object2里和object1值不一样的字段,同时让TypeScript能精确推导返回类型(不能只是宽泛的Partial<T>)。目前的实现代码如下:

const diff = <T extends {}>(object1: T, object2: T) => {
  const diffValues = {}
  for (const key in object1) {
    if (object1[key] !== object2[key]) {
      diffValues[key] = object2[key]
    }
  }
  return diffValues;
}

期望的类型推导效果:

const res = diff({ a: 1 }, { a: 2 }) // 返回类型 { a: number }
const res = diff({ a: 1, b: 'value' }, { a: 1, b: 'value2' }) // 返回类型 { b: string }

试过lodash的omit工具函数但没成功,想知道怎么让TypeScript更精准地推导返回类型。

解决方案

要做到精确类型推导,得用TypeScript的条件类型和映射类型来过滤值不同的字段,同时在函数里做类型断言保证类型安全。

1. 定义差异类型

先定义一个Diff<T, U>类型,用来提取T和U中值类型不同的字段:

type Diff<T, U> = {
  [K in keyof T as T[K] extends U[K] ? never : K]: U[K]
} & {}

这个类型会遍历T的所有键,当T[K]和U[K]类型不一样时保留该键,否则排除。最后加& {}是为了让类型在编辑器里展示得更清晰。

2. 实现带精确类型的diff函数

修改原函数,用泛型约束和类型断言让返回值对应Diff<T, U>:

const diff = <T extends object, U extends T>(object1: T, object2: U): Diff<T, U> => {
  const diffValues = {} as Diff<T, U>;
  for (const key in object1) {
    if (object1[key] !== object2[key]) {
      diffValues[key as keyof Diff<T, U>] = object2[key] as Diff<T, U>[keyof Diff<T, U>];
    }
  }
  return diffValues;
}

3. 验证效果

测试几个示例:

// 返回类型 { a: number }
const res1 = diff({ a: 1 }, { a: 2 })
// 返回类型 { b: string }
const res2 = diff({ a: 1, b: 'value' }, { a: 1, b: 'value2' })
// 返回类型 {}(所有字段值都相同)
const res3 = diff({ a: 1, b: 'test' }, { a: 1, b: 'test' })

关键点说明

  • 泛型U extends T确保object2是object1的子类型,避免出现object2有额外字段的情况
  • Diff<T, U>通过条件类型过滤出类型不同的字段,再结合运行时的!==校验,保证返回的是实际值不同的字段
  • 类型断言as Diff<T, U>让TypeScript认可返回值的精确类型,不会再推断成宽泛的{}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:50:20