I know this is a bit of an old issue but the easiest solution in ES2015/ES6 I could come up with was actually quite simple, using Object.assign(),

Hopefully this helps:

/**
 * Simple object check.
 * @param item
 * @returns {boolean}
 */
export function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

/**
 * Deep merge two objects.
 * @param target
 * @param ...sources
 */
export function mergeDeep(target, ...sources) {
  if (!sources.length) return target;
  const source = sources.shift();

  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }

  return mergeDeep(target, ...sources);
}

Example usage:

mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }

You'll find an immutable version of this in the answer below.

Note that this will lead to infinite recursion on circular references. There's some great answers on here on how to detect circular references if you think you'd face this issue.

Answer from Salakar on Stack Overflow
๐ŸŒ
DEV Community
dev.to โ€บ svehla โ€บ typescript-how-to-deep-merge-170c
How to deep merge in Typescript - DEV Community
October 5, 2021 - Letโ€™s created a proper generic that recursively deep merge Typescript types. First of all, we define 2 helper generic types. type GetObjDifferentKeys< T, U, T0 = Omit<T, keyof U> & Omit<U, keyof T>, T1 = { [K in keyof T0]: T0[K] } > = T1 ยท this type takes 2 Objects and returns a new object contains only unique keys in A and B.
Discussions

javascript - How to deep merge instead of shallow merge?
If npm libraries can be used as a solution, object-merge-advanced from yours truly allows to merge objects deeply and customise/override every single merge action using a familiar callback function. The main idea of it is more than just deep merging โ€” what happens with the value when two keys ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Help with typing a deep merge function.
I'm sure your running into a snag more complex than my suggestion, but if you already have a function that can deep merge two objects, couldn't you just recursively call that function against all the objects in the array? Or just use reduce and do the same thing? What are the roadblocks you are running into? More on reddit.com
๐ŸŒ r/typescript
10
7
November 9, 2020
How to combine object properties in typescript? - Stack Overflow
Use Typescript spread operator it transpile to Javascript Object.assign() If you need deep tree object merging you could use changing function of best-global package ... Save this answer. ... Show activity on this post. Lodash has an "extend" function that combines objects and lets Typescirpt know that the new object has the type you'd expect. const a = { one: 1, two... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Deep Merging Utility Types
This feature would agree with the rest of TypeScript's Design Goals. Deep type merges with objects that have enums or functions props are not fully possible in Typescript, nor are their "best" implementations very performant or transparent. More on github.com
๐ŸŒ github.com
June 18, 2021
๐ŸŒ
Aaron Bos
aaronbos.dev โ€บ posts โ€บ merge-objects-typescript-javascript
Merging Objects in TypeScript (and JavaScript)
June 11, 2022 - The Object.assign method copies all enumerable (propertyIsEnumerable(prop) returns true) own properties from one or many source objects to a target object. The source object(s) properties are applied to the target object, which is then returned from the method after it has been modified. Since Object.assign performs a shallow merge operation, only properties one level deep will be "merged".
๐ŸŒ
Sandtoken
sandtoken.com โ€บ writing โ€บ typescript-deep-merge-explained
Deep Merge in TypeScript - A Type-Safe Approach to Object Combination
October 19, 2024 - The deep merge utility provides a robust, type-safe solution for combining nested objects in TypeScript applications.
Top answer
1 of 15
317

I know this is a bit of an old issue but the easiest solution in ES2015/ES6 I could come up with was actually quite simple, using Object.assign(),

Hopefully this helps:

/**
 * Simple object check.
 * @param item
 * @returns {boolean}
 */
export function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

/**
 * Deep merge two objects.
 * @param target
 * @param ...sources
 */
export function mergeDeep(target, ...sources) {
  if (!sources.length) return target;
  const source = sources.shift();

  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }

  return mergeDeep(target, ...sources);
}

Example usage:

mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }

You'll find an immutable version of this in the answer below.

Note that this will lead to infinite recursion on circular references. There's some great answers on here on how to detect circular references if you think you'd face this issue.

2 of 15
253

You can use Lodash merge:

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};

var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};

console.log(_.merge(object, other));
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

๐ŸŒ
GitHub
github.com โ€บ voodoocreation โ€บ ts-deepmerge
GitHub - voodoocreation/ts-deepmerge: A TypeScript deep merge function with automatically inferred types. ยท GitHub
Objects and arrays will be merged, but values such as numbers and strings will be overwritten. All merging/overwriting occurs in the order of the arguments you provide the function with. Both ESM and CommonJS are supported by this package. import { merge } from "ts-deepmerge"; const obj1 = { a: { a: 1 } }; const obj2 = { b: { a: 2, b: 2 } }; const obj3 = { a: { b: 3 }, b: { b: 3, c: 3 }, c: 3 }; const result = merge(obj1, obj2, obj3);
Author: voodoocreation
๐ŸŒ
Reddit
reddit.com โ€บ r/typescript โ€บ help with typing a deep merge function.
r/typescript on Reddit: Help with typing a deep merge function.
November 9, 2020 -

Hey all, I'm wondering if there are any smart people out there looking a little bit of a challenge. On the surface this didn't seem like it would be very hard when I started but it's been a lot more difficult than I expected.

But anyway, essentially I'm trying to type 2 functions. One that will deeply merge any 2 given objects into a new resulting object. And the other that will deeply merge an array of 2+ objects into a new resulting object.

I feel I'm close to getting the typings all correct but I'm having trouble with the second of the 2 functions. I'd really appreciate any help with solving this issue. I'd also really love if anyone was able to peer review my current PR.

https://github.com/TehShrike/deepmerge/pull/211

Thanks for reading :)

Find elsewhere
๐ŸŒ
Amitd
amitd.co โ€บ code โ€บ typescript โ€บ recursively-deep-merging-objects
Recursively deep merging objects โ€” Typescript โ€” Amit Dhamu โ€” Staff Engineer
[]).forEach(([key, value]) => { if (value) { if (!target[key]) { Object.assign(target, { [key]: {} }) } if ( value.constructor === Object || (value.constructor === Array && value.find(v => v.constructor === Object)) ) { deepMerge(target[key], value) } else if (value.constructor === Array) { Object.assign(target, { [key]: value.find(v => v.constructor === Array) ?
๐ŸŒ
npm
npmjs.com โ€บ package โ€บ ts-deepmerge
ts-deepmerge - npm
May 22, 2026 - A deep merge function that automatically infers the return type based on your input, without mutating the source objects.
      ยป npm install ts-deepmerge
    
Published: May 22, 2026
Version: 8.0.0
๐ŸŒ
GitHub
gist.github.com โ€บ mir4ef โ€บ c172583bdb968951d9e57fb50d44c3f7
Deep merging of JavaScript objects (in TypeScript) ยท GitHub
thanks, the return of deepMerge should be a combination of the passed objects, not IObject, TS complains otherwise
๐ŸŒ
Omarileon
omarileon.me โ€บ blog โ€บ typescript-merge-objects
mari. | 3 Simple Ways to Merge Objects in TypeScript
January 26, 2024 - So to sum things up, to merge objects in TypeScript, you can use either the spread syntax, Lodash's merge function, or Object.assign. ... Object.assign is a bit more verbose, but lets you merge one object into another without creating a new one ยท Lodash merge does a deep merge/clone, but is an additional dependency
๐ŸŒ
ThisCodeWorks
thiscodeworks.com โ€บ deep-merging-of-js-objects-in-typescript-javascript-typescript โ€บ 5f92af82d4244600141b6e57
Deep merging of JS objects (in TypeScript) | thiscodeWorks
October 23, 2020 - * @param item - The item that needs to be checked * @return {Boolean} Whether or not @item is an object */ export const isObject: IIsObject = (item: any): boolean => { return (item === Object(item) && !Array.isArray(item)); }; /** * @description Method to perform a deep merge of objects * @param {Object} target - The targeted object that needs to be merged with the supplied @sources * @param {Array<Object>} sources - The source(s) that will be used to update the @target object * @return {Object} The final merged object */ export const deepMerge: IDeepMerge = (target: IObject, ...sources: Array
๐ŸŒ
GitHub
gist.github.com โ€บ ahtcx โ€บ 0cd94e62691f539160b32ecda18af3d6
Deep-Merge JavaScript objects with ES6 ยท GitHub
This solution is for iteratively merge any number of objects (it's typed with TypeScript, you might need to remove typings before using on regular JS projects): export function deepMerge(...objects: object[]) { const isObject = (obj: any) => obj && typeof obj === 'object'; function deepMergeInner(target: object, source: object) { Object.keys(source).forEach((key: string) => { const targetValue = target[key]; const sourceValue = source[key]; if (Array.isArray(targetValue) && Array.isArray(sourceValue)) { target[key] = targetValue.concat(sourceValue); } else if (isObject(targetValue) && isObject
๐ŸŒ
Tim Mousk
timmousk.com โ€บ blog โ€บ typescript-merge-objects
How To Merge Objects In TypeScript? โ€“ Tim Mouskhelichvili
March 27, 2023 - Indeed, this function does a deep copy, so the newly created object will NOT share any references with the original objects. Before using this function, you must install Lodash using npm or yarn.
๐ŸŒ
npm
npmjs.com โ€บ package โ€บ object-deep-merge
object-deep-merge - npm
October 20, 2025 - type Data = { name: string; description: string; }; const base: Data = { name: "object-deep-merge", description: "merge objects" }; const overrides: Partial<Data> = { description: "merge objects, deeply" }; const merged = merge(base, overrides); // Type is inferred so the signature becomes: // function merge<Partial<Data>, Partial<Data>>(source: Partial<Data>, target: Partial<Data>, ...targets: Partial<Data>[]): Partial<Data> // TData = Partial<Data> // TResult = Data console.log({ merged });
      ยป npm install object-deep-merge
    
Published: May 19, 2026
Version: 2.0.1
๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-deep-merge-objects
A Comprehensive Guide to Deep Merging Objects in TypeScript
Deep merging involves recursively ... data structures with multiple levels of nesting. One way to achieve deep merging in TypeScript is by using recursive functions....
๐ŸŒ
Webdevtutor
webdevtutor.net โ€บ blog โ€บ typescript-object-deep-merge
A Comprehensive Guide to TypeScript Object Deep Merge
There are several approaches to achieving object deep merge in TypeScript. One common method is to use a recursive function that iterates through the properties of each object and merges them accordingly.
๐ŸŒ
npm
npmjs.com โ€บ package โ€บ deepmerge
deepmerge - npm
March 16, 2023 - Merges the enumerable properties of two or more objects deeply.
      ยป npm install deepmerge
    
Published: Mar 16, 2023
Version: 4.3.1
๐ŸŒ
GitHub
github.com โ€บ microsoft โ€บ TypeScript โ€บ issues โ€บ 44660
Deep Merging Utility Types ยท Issue #44660 ยท microsoft/TypeScript
June 18, 2021 - This feature would agree with the rest of TypeScript's Design Goals. Deep type merges with objects that have enums or functions props are not fully possible in Typescript, nor are their "best" implementations very performant or transparent.