forked from remeda/remeda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clone.ts
65 lines (61 loc) · 1.63 KB
/
clone.ts
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
// 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: Array<any>,
refTo: Array<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;
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
* @category Object
* @signature R.clone(value)
* @example R.clone({foo: 'bar'}) // {foo: 'bar'}
*/
export function clone<T>(value: T): T {
return value != null && typeof (value as any).clone === 'function'
? (value as any).clone()
: _clone(value, [], [], true);
}