All files / src/core/utils extend.ts

100% Statements 21/21
100% Branches 26/26
100% Functions 2/2
100% Lines 21/21

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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                      180x     180x 3x     180x   1080x   217x 632x       632x 1x     631x     631x 126x 126x     126x 33x 93x 76x       126x     505x 504x             180x      
import { isArray, isFunction, isPlainObject, isNull } from 'core/utils/types';
import { each } from 'core/utils/arrays';
 
// https://github.com/jquery/jquery/blob/master/src/core.js#L116
export function extend<T, U>(target: T, object1: U): T & U;
export function extend<T, U, V>(target: T, object1: U, object2: V): T & U & V;
export function extend<T, U, V, W>(target: T, object1: U, object2: V, object3: W): T & U & V & W;
export function extend<T, U, V, W, X>(target: T, object1: U, object2: V, object3: W, object4: X): T & U & V & W & X;
export function extend<T, U, V, W, X, Y>(target: T, object1: U, object2: V, object3: W, object4: X, object5: Y): T & U & V & W & X & Y;
export function extend<T, U, V, W, X, Y, Z>(
  target: T,
  object1?: U,
  object2?: V,
  object3?: W,
  object4?: X,
  object5?: Y,
  object6?: Z,
): T & U & V & W & X & Y & Z {
  /* eslint-disable no-restricted-syntax, guard-for-in */
  const sources: Array<any> = [object1, object2, object3, object4, object5, object6];
 
  // Handle case when target is a string or something (possible in deep copy)
  if ((typeof target !== 'object' || isNull(target)) && !isFunction(target)) {
    target = {} as T;
  }
 
  each(sources, (source) => {
    // Only deal with non-null/undefined values
    if (source != null) {
      // Extend the base object
      for (const name in source) {
        const copy: any = source[name];
 
        // Prevent Object.prototype pollution
        // Prevent never-ending loop
        if (name === '__proto__' || target === copy) {
          continue;
        }
 
        const copyIsArray = isArray(copy);
 
        // Recurse if we're merging plain objects or arrays
        if (copy && (isPlainObject(copy) || copyIsArray)) {
          const src = target[name];
          let clone: any = src;
 
          // Ensure proper type for the source value
          if (copyIsArray && !isArray(src)) {
            clone = [];
          } else if (!copyIsArray && !isPlainObject(src)) {
            clone = {};
          }
 
          // Never move original objects, clone them
          target[name] = extend(clone, copy) as any;
 
          // Don't bring in undefined values
        } else if (copy !== undefined) {
          target[name] = copy;
        }
      }
    }
  });
 
  // Return the modified object
  return target as any;
  /* eslint-enable */
}