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

TypeScript如何基于RecursivePartial实现嵌套对象深度更新

递归深度更新对象实现方案

第一步:定义支持嵌套和数组的RecursivePartial类型

原始的RecursivePartial未适配数组结构,修改后可兼容数组、多层嵌套对象场景:

export type RecursivePartial<T> = {
  [P in keyof T]?: 
    T[P] extends (infer U)[] ? RecursivePartial<U>[] :
    T[P] extends object ? RecursivePartial<T[P]> :
    T[P];
};

第二步:实现深度合并函数

函数会递归遍历所有层级的属性,仅覆盖更新对象中存在的字段,其余原值保留,同时适配数组类型的合并:

export function updateFromPartial<T>(obj: T, updates: RecursivePartial<T>): T {
  // 基础类型、null的场景直接返回更新值
  if (updates === null || typeof updates !== 'object') {
    return updates as T;
  }
  // 数组场景按索引合并对应项
  if (Array.isArray(obj) && Array.isArray(updates)) {
    return updates.map((updateItem, index) => 
      updateFromPartial(obj[index], updateItem)
    ) as unknown as T;
  }
  // 普通对象场景递归合并每个属性
  const merged = {...obj};
  for (const key in updates) {
    if (Object.prototype.hasOwnProperty.call(updates, key)) {
      merged[key] = updateFromPartial(
        obj[key], 
        updates[key] as RecursivePartial<typeof obj[key]>
      );
    }
  }
  return merged;
}

使用示例

以你定义的SalesOrder接口为例,效果如下:

export interface SalesOrder {
  id: number,
  DeliveryInfo: {
    Address: {
      province: string,
      city: string
    },
    DeliveryTime: string
  },
  items: {id: number, name: string, count: number}[]
}

// 原始对象
const originalOrder: SalesOrder = {
  id: 1,
  DeliveryInfo: {
    Address: {
      province: '广东',
      city: '深圳'
    },
    DeliveryTime: '2024-01-01'
  },
  items: [
    {id: 1, name: '商品1', count: 2},
    {id: 2, name: '商品2', count: 3}
  ]
};

// 仅更新指定嵌套字段,其余字段自动保留
const updatedOrder = updateFromPartial(originalOrder, {
  DeliveryInfo: {
    DeliveryTime: '2024-02-01'
  },
  items: [
    {count: 5}
  ]
});

// 输出验证
console.log(updatedOrder.DeliveryInfo.Address.province); // 广东 原值保留
console.log(updatedOrder.DeliveryInfo.DeliveryTime); // 2024-02-01 字段更新成功
console.log(updatedOrder.items[0].count); // 5 数组成员字段更新成功
console.log(updatedOrder.items[0].name); // 商品1 数组成员其余字段保留

可选调整说明

  • 如果需要跳过值为undefined的更新字段,可在对象属性遍历逻辑中增加if (updates[key] === undefined) continue判断
  • 如果数组需要按业务ID匹配而非索引匹配合并,可修改数组处理逻辑,遍历更新数组的元素,按ID找到原数组对应项再合并

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:36:04