deepmerge
    DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/deepmerge package

    4.2.2 • Public • Published

    deepmerge

    Merges the enumerable properties of two or more objects deeply.

    UMD bundle is 723B minified+gzipped

    Getting Started

    Example Usage

    const x = {
        foo: { bar: 3 },
        array: [{
            does: 'work',
            too: [ 1, 2, 3 ]
        }]
    }
     
    const y = {
        foo: { baz: 4 },
        quux: 5,
        array: [{
            does: 'work',
            too: [ 4, 5, 6 ]
        }, {
            really: 'yes'
        }]
    }
     
    const output = {
        foo: {
            bar: 3,
            baz: 4
        },
        array: [{
            does: 'work',
            too: [ 1, 2, 3 ]
        }, {
            does: 'work',
            too: [ 4, 5, 6 ]
        }, {
            really: 'yes'
        }],
        quux: 5
    }
     
    merge(x, y) // => output

    Installation

    With npm do:

    npm install deepmerge

    deepmerge can be used directly in the browser without the use of package managers/bundlers as well: UMD version from unpkg.com.

    Include

    deepmerge exposes a CommonJS entry point:

    const merge = require('deepmerge')
    

    The ESM entry point was dropped due to a Webpack bug.

    API

    merge(x, y, [options])

    Merge two objects x and y deeply, returning a new merged object with the elements from both x and y.

    If an element at the same key is present for both x and y, the value from y will appear in the result.

    Merging creates a new object, so that neither x or y is modified.

    Note: By default, arrays are merged by concatenating them.

    merge.all(arrayOfObjects, [options])

    Merges any number of objects into a single result object.

    const foobar = { foo: { bar: 3 } }
    const foobaz = { foo: { baz: 4 } }
    const bar = { bar: 'yay!' }
     
    merge.all([ foobar, foobaz, bar ]) // => { foo: { bar: 3, baz: 4 }, bar: 'yay!' }

    Options

    arrayMerge

    There are multiple ways to merge two arrays, below are a few examples but you can also create your own custom function.

    Your arrayMerge function will be called with three arguments: a target array, the source array, and an options object with these properties:

    • isMergeableObject(value)
    • cloneUnlessOtherwiseSpecified(value, options)

    arrayMerge example: overwrite target array

    Overwrites the existing array values completely rather than concatenating them:

    const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
     
    merge(
        [1, 2, 3],
        [3, 2, 1],
        { arrayMerge: overwriteMerge }
    ) // => [3, 2, 1]

    arrayMerge example: combine arrays

    Combines objects at the same index in the two arrays.

    This was the default array merging algorithm pre-version-2.0.0.

    const combineMerge = (target, source, options) => {
        const destination = target.slice()
     
        source.forEach((item, index) => {
            if (typeof destination[index] === 'undefined') {
                destination[index] = options.cloneUnlessOtherwiseSpecified(item, options)
            } else if (options.isMergeableObject(item)) {
                destination[index] = merge(target[index], item, options)
            } else if (target.indexOf(item) === -1) {
                destination.push(item)
            }
        })
        return destination
    }
     
    merge(
        [{ a: true }],
        [{ b: true }, 'ah yup'],
        { arrayMerge: combineMerge }
    ) // => [{ a: true, b: true }, 'ah yup']

    isMergeableObject

    By default, deepmerge clones every property from almost every kind of object.

    You may not want this, if your objects are of special types, and you want to copy the whole object instead of just copying its properties.

    You can accomplish this by passing in a function for the isMergeableObject option.

    If you only want to clone properties of plain objects, and ignore all "special" kinds of instantiated objects, you probably want to drop in is-plain-object.

    const isPlainObject = require('is-plain-object')
     
    function SuperSpecial() {
        this.special = 'oh yeah man totally'
    }
     
    const instantiatedSpecialObject = new SuperSpecial()
     
    const target = {
        someProperty: {
            cool: 'oh for sure'
        }
    }
     
    const source = {
        someProperty: instantiatedSpecialObject
    }
     
    const defaultOutput = merge(target, source)
     
    defaultOutput.someProperty.cool // => 'oh for sure'
    defaultOutput.someProperty.special // => 'oh yeah man totally'
    defaultOutput.someProperty instanceof SuperSpecial // => false
     
    const customMergeOutput = merge(target, source, {
        isMergeableObject: isPlainObject
    })
     
    customMergeOutput.someProperty.cool // => undefined
    customMergeOutput.someProperty.special // => 'oh yeah man totally'
    customMergeOutput.someProperty instanceof SuperSpecial // => true

    customMerge

    Specifies a function which can be used to override the default merge behavior for a property, based on the property name.

    The customMerge function will be passed the key for each property, and should return the function which should be used to merge the values for that property.

    It may also return undefined, in which case the default merge behaviour will be used.

    const alex = {
        name: {
            first: 'Alex',
            last: 'Alexson'
        },
        pets: ['Cat', 'Parrot']
    }
     
    const tony = {
        name: {
            first: 'Tony',
            last: 'Tonison'
        },
        pets: ['Dog']
    }
     
    const mergeNames = (nameA, nameB) => `${nameA.first} and ${nameB.first}`
     
    const options = {
        customMerge: (key) => {
            if (key === 'name') {
                return mergeNames
            }
        }
    }
     
    const result = merge(alex, tony, options)
     
    result.name // => 'Alex and Tony'
    result.pets // => ['Cat', 'Parrot', 'Dog']

    clone

    Deprecated.

    Defaults to true.

    If clone is false then child objects will be copied directly instead of being cloned. This was the default behavior before version 2.x.

    Testing

    With npm do:

    npm test

    License

    MIT

    Install

    npm i deepmerge

    DownloadsWeekly Downloads

    19,364,842

    Version

    4.2.2

    License

    MIT

    Unpacked Size

    30.1 kB

    Total Files

    9

    Last publish

    Collaborators

    • tehshrike