All files clone.ts

100% Statements 21/21
82.61% Branches 19/23
100% Functions 4/4
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    13x     8x                       130x 130x 130x 340x 4x   336x   126x 126x   126x 199x       126x   264x   87x   43x   2x   8x   124x                     13x   65x          
// from https://github.com/ramda/ramda/blob/master/source/internal/_clone.js
 
import { type } from './type';
 
function _cloneRegExp(pattern: RegExp) {
  return new RegExp(
    pattern.source,
    (pattern.global ? 'g' : '') +
      (pattern.ignoreCase ? 'i' : '') +
      (pattern.multiline ? 'm' : '') +
      (pattern.sticky ? 'y' : '') +
      (pattern.unicode ? 'u' : '')
  );
}
 
function _clone(value: any, refFrom: any[], refTo: any[], deep: boolean) {
  function copy(copiedValue: any) {
    const len = refFrom.length;
    let idx = 0;
    while (idx < len) {
      if (value === refFrom[idx]) {
        return refTo[idx];
      }
      idx += 1;
    }
    refFrom[idx + 1] = value;
    refTo[idx + 1] = copiedValue;
    // tslint:disable-next-line:forin
    for (const key in value) {
      copiedValue[key] = deep
        ? _clone(value[key], refFrom, refTo, true)
        : value[key];
    }
    return copiedValue;
  }
  switch (type(value)) {
    case 'Object':
      return copy({});
    case 'Array':
      return copy([]);
    case 'Date':
      return new Date(value.valueOf());
    case 'RegExp':
      return _cloneRegExp(value);
    default:
      return value;
  }
}
 
/**
 * Creates a deep copy of the value. Supported types: `Array`, `Object`, `Number`, `String`, `Boolean`, `Date`, `RegExp`. Functions are assigned by reference rather than copied.
 * @param value - the object to clone
 * @signature P.clone(value)
 * @example P.clone({foo: 'bar'}) // {foo: 'bar'}
 * @category Object
 */
export function clone<T extends any>(value: T): T {
  // @ts-ignore
  return value != null && typeof value.clone === 'function'
    ? // @ts-ignore
      value.clone()
    : _clone(value, [], [], true);
}