All files / src/utils merge.ts

92.59% Statements 25/27
55.55% Branches 5/9
100% Functions 2/2
92.59% Lines 25/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 281x 1x 1x 1x 1x 1x 1x 1x 12x 12x 12x 24x 156x 156x 156x 156x   156x   156x 156x 156x 24x 24x 24x 12x 12x  
/**
 * Performs a deep merge of objects and returns new object. Does not modify
 * objects (immutable) and merges arrays via concatenation.
 *
 * @param {...object} objects - Objects to merge
 * @returns {object} New object with merged key/values
 */
export function merge<T extends Record<string, any>>(...objects: Array<T>): T {
  const isObject = (obj: unknown) => obj && typeof obj === 'object';
 
  return objects.reduce<Record<string, unknown>>((prev, obj) => {
    Object.keys(obj).forEach((key) => {
      const pVal = prev[key];
      const oVal = obj[key];
 
      if (Array.isArray(pVal) && Array.isArray(oVal)) {
        prev[key] = pVal.concat(...oVal);
      } else if (isObject(pVal) && isObject(oVal)) {
        prev[key] = merge(pVal, oVal);
      } else {
        prev[key] = oVal;
      }
    });
 
    return prev;
  }, {}) as T;
}