merge-deep-ts
TypeScript icon, indicating that this package has built-in type declarations

1.2.12 • Public • Published

GitHub package.json version npm bundle size GitHub Workflow Status Testspace pass ratio Coverage Status GitHub license

Deep fast merge JavaScript objects with circular references handling and TypeScript support

Installation

# Install with npm
npm install deep-merge-ts
# Install with yarn
yarn add deep-merge-ts

Usage

Once the package is installed, you can import the library using import or require approach:

import merge from "merge-deep-ts";

or

const merge = require("merge-deep-ts").default;

Features

  • Merges deeply objects
  • Supports Object, Array, Map or Set merge
  • Input objects can have any circular references
  • Fast algorithm with caching
  • Strongly typed merged result with TypeScript
  • No dependencies
  • Small size
  • Works in browser and Node.js

Examples

Objects

const bookInfo = {
    title: "Harry Potter",
    year: 1997,
    price: {
        value: 69,
        currency: "USD"
    }
};

const bookDiscount = {
    title: "Harry Potter and the Philosopher's Stone",
    price: {
        value: 49
    }
};

const book = merge([bookInfo, bookDiscount]);

// const book: {
//     title: string;
//     year: number;
//     price: {
//         value: number;
//         currency: string;
//     };
// };

You can use as const to get more precise types:

const bookInfo = {
    title: "Harry Potter",
    year: 1997,
    price: {
        value: 69,
        currency: "USD"
    }
} as const;

const bookDiscount = {
    title: "Harry Potter and the Philosopher's Stone",
    price: {
        value: 49
    }
} as const;

const book = merge([bookInfo, bookDiscount]);

// const book: {
//     title: "Harry Potter and the Philosopher's Stone";
//     year: 1997;
//     price: {
//         value: 49;
//         currency: "USD";
//     };
// };

Runtime JS result:

{
  title: "Harry Potter and the Philosopher's Stone",
  year: 1997,
  price: {
    value: 49,
    currency: "USD"
  }
}

Arrays

Arrays are merged by index. If the index is not present in the first array, the value is taken from the second array.

const books = merge([
    [
        { title: "Harry Potter" },
        { title: "Lord of the Rings" }
    ], [
        { author: "J. K. Rowling", birthYear: 1965 },
        { author: "J. R. R. Tolkien" }
    ], [
        { year: 1997 },
        { year: 1954, ISBN: "123-456-789" }
    ],
]);

// const books: [{
//     title: string;
//     author: string;
//     year: number;
//     birthYear: number;
// }, {
//     title: string;
//     author: string;
//     year: number;
//     ISBN: string;
// }];

You can use as const to get more precise types:

const titles = [
    { title: "Harry Potter" },
    { title: "Lord of the Rings" }
] as const;

const authors = [
    { author: "J. K. Rowling", birthYear: 1965 },
    { author: "J. R. R. Tolkien" }
] as const;

const info = [
    { year: 1997 },
    { year: 1954, ISBN: "123-456-789" }
] as const;

const books = merge([titles, authors, info]);

// const books: [{
//     title: "Harry Potter";
//     author: "J. K. Rowling";
//     birthYear: 1965;
//     year: 1997;
// }, {
//     title: "Lord of the Rings";
//     author: "J. R. R. Tolkien";
//     year: 1954;
//     ISBN: "123-456-789";
// }];

Runtime JS result:

[
  {
    title: "Harry Potter",
    author: "J. K. Rowling",
    birthYear: 1965,
    year: 1997
  }, {
    title: "Lord of the Rings",
    author: "J. R. R. Tolkien",
    year: 1954,
    ISBN: "123-456-789"
  }
]

Maps

const phone = new Map([
    ["name", "iPhone"],
    ["model", "14"],
    ["price", { value: 999, currency: "USD" }],
	["owners", [
            { name: "Alex", age: 30 }
    ]]
]);

const phoneUpdate = new Map([
    ["model", "14 used"],
    ["price", { value: 699, currency: "USD" }],
    ["owners", [
        { name: "Alex", age: 35 },
        { name: "John", age: 42 }
    ]]
]);

const updatedPhone = merge([phone, phoneUpdate]);

Runtime JS result:

Map {
  name => "iPhone",
  model => "14 used",
  price => {
    value => 699,
    currency => "USD"
  },
  owners => [{
    name => "Alex",
    age => 35
  }, {
    name => "John",
    age => 42
  }]
}

Sets

const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const mergedSet = merge([set1, set2]);

Runtime JS result:

Set { 1, 2, 3, 4 }

Circular references

const bookInfo = {
    title: "Harry Potter",
    price: 49,
    year: 1997,
    author: {
        name: "Joanne Rowling",
        books: [] // → [bookInfo]
    }
};
bookInfo.author.books.push(bookInfo); // add circular reference

const bookSale = {
    title: "Harry Potter (sale)",
    price: 29,
    author: {
        name: "J. K. Rowling"
    }
};

const book = merge([bookInfo, bookSale]);

Runtime JS result:

{
  title: "Harry Potter and the Philosopher's Stone",
  price: 29,
  year: 1997,
  author: {
    name: "J. K. Rowling",
    books: [/* Circular reference */]
  }
}

Circular cross-references

// object1 = { a: 1, o2: object2 }
// object2 = { b: 2, o1: object1 }
const object1 = { a: 1 };
const object2 = { b: 2 };
object1.o2 = object2;
object2.o1 = object1;

const merged = merge([object1, object2]);

Runtime JS result:

{
  a: 1,
  b: 2,
  o1: {
    a: 1,
    o2: [/* Circular reference → merged.o2 */]
  },
  o2: {
    b: 2,
    o1: [/* Circular reference → merged.o1 */]
  }
}

Package Sidebar

Install

npm i merge-deep-ts

Weekly Downloads

14

Version

1.2.12

License

MIT

Unpacked Size

27.8 kB

Total Files

14

Last publish

Collaborators

  • ichernetskii