merge-objects
Merges multiple objects into a new object.
Compared to Object.assign() or object spreads {...obj1, ...obj2}, values are not assigned as a whole. Instead, properties that don't hold the value undefined are recursively merged. The difference to Lodash's _.merge or jQuery's deep extend is that arrays are concatenated.
Features:
- Type-safe: computes intersection of input arguments
- Fail-safe: allows any input type but only merges objects
- Immutable: creates a new object instead of assigning to the first argument
- Concatenates arrays []
- Recursively merges objects {}
- Skips undefined properties
- Overwrites properties if value is not undefined
- Merges up to 4 objects, composes for more.
Installation
npm i @danieldietrich/merge-objects
Usage
The module supports ES6 import and CommonJS require style.
import mergeObjects from '@danieldietrich/merge-objects';
// -- merge n objects
// = {a: {b: 2, c: [1, 2], d: 3, e: 4}}
mergeObjects(
{a: {b: 1, c: [1], d: 3}},
{a: {b: 2, c: [2]}},
{} || undefined,
{a: {b: undefined, e: 4}}
);
// -- remove undefined properties
// = {b: [1, undefined, 2], c: {}}
mergeObjects(
{a: undefined, b: [1, undefined, 2], c: {d: undefined}}
);
Type safety
While merge-objects works well with JavaScript, it comes with TypeScript types. The merged object type is inferred by the TypeScript compiler:
/*
const o: {
0: number;
a: number;
b: number[];
c: number[];
f: () => void;
} & {
0: number;
a: string;
b: number[];
c: string[];
f: (arg: number) => true;
}
*/
const o = mergeObjects(
{0: 1, a: 1, b: [1], c: [1], f: () => {}},
{0: 2, a: "2", b: [2], c: ["2"], f: (arg: number) => true},
{} || undefined,
);
// const first: number
const first = o[0];
// const b: number[]
const b = o.b;
// compiler error "Property 'x' does not exist on type '...'."
const x = o.x;
// computed type: string & number, eff. never;
// actual type: string
const a = o.a;
// computed type: number[] & string[], eff. never[]
// actual type: Array<number | string>
const c = o.c;
// computed type: (() => void) & ((arg: number) => true)
// actual type: ((arg: number) => true)
const f = o.f;
Bottom line: thou shalt not merge incompatible objects.
Copyright © 2020 by Daniel Dietrich. Released under the MIT license.