All files / core/src/utility assign.ts

100% Statements 44/44
100% Branches 5/5
100% Functions 1/1
100% Lines 44/44

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 451x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 340x 340x 340x 340x 449x 449x 17x 741x 741x 449x 449x 449x 340x 340x 340x  
import { Merge } from '../typing/merge';
import { TypeOf } from './type-of';
 
/**
 * **assign**s (deep copies) the values of all of the enumerable own properties
 * from one or more `sources` to a `target`. The last value within the last
 * `sources` object takes precedence over any previously encountered values.
 *
 * @param target - The `target` object to **assign** properties to.
 * @param sources - An array of `sources` from which to deep copy properties.
 * @typeParam T - The type of the `target` object.
 * @typeParam S - The types of the `sources` objects.
 * @returns The **assign**ed-to `target` object.
 *
 * @example
 * **assign** nested properties:
 * ```ts
 * import { assign } from '@sgrud/core';
 *
 * assign(
 *   { one: { one: true }, two: false },
 *   { one: { key: null } },
 *   { two: true }
 * );
 *
 * // { one: { one: true, key: null }, two: true }
 * ```
 */
export function assign<
  T extends Record<PropertyKey, any>,
  S extends Record<PropertyKey, any>[]
>(target: T, ...sources: [...S]): T & Merge<S[number]> {
  for (const source of sources) {
    for (const key in source) {
      if (TypeOf.object(target[key]) && TypeOf.object(source[key])) {
        target[key] = assign({} as any, target[key], source[key]);
      } else {
        target[key] = source[key];
      }
    }
  }
 
  return target as T & Merge<S[number]>;
}