param originalObject param overrideObject param config returns export function mergeDeep ( originalObject , overrideObject , config = { mergeArrays : false } ) { const isObject = ( obj ) => obj && typeof obj === 'object' ; return [ originalObject , overrideObject ] . reduce ( ( mergedObject , obj ) => { Object . keys ( obj ) . forEach ( ( key ) => { const mergedObjectValue = mergedObject [ key ] ; const overrideObjectValue = obj [ key ] ; if ( Array . isArray ( mergedObjectValue ) && Array . isArray ( overrideObjectValue ) ) { mergedObject [ key ] = config . mergeArrays ? mergedObjectValue . concat ( overrideObjectValue ) : overrideObjectValue ; } else if ( isObject ( mergedObjectValue ) && isObject ( overrideObjectValue ) ) { mergedObject [ key ] = mergeDeep ( mergedObjectValue , overrideObjectValue ) ; } else { mergedObject [ key ] = overrideObjectValue ; } } ) ; return mergedObject ; } , { } ) ; } export function mergeDeepAll ( ... objects ) { const objectsWithoutUndefined = objects . filter ( ( object ) => object !== undefined ) ; return objectsWithoutUndefined . reduce ( ( originalObject , overrideObject ) => mergeDeep ( originalObject , overrideObject ) ) ; }