-
-
Notifications
You must be signed in to change notification settings - Fork 370
Expand file tree
/
Copy path_merge.ts
More file actions
96 lines (82 loc) 路 2.43 KB
/
Copy path_merge.ts
File metadata and controls
96 lines (82 loc) 路 2.43 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { _sameValueZero } from '../../../../utils/index.ts';
/**
* Merge dataset type.
*/
type MergeDataset =
| { value: unknown; issue?: undefined }
| { value?: undefined; issue: true };
/**
* Merges two values into one single output.
*
* @param value1 First value.
* @param value2 Second value.
*
* @returns The merge dataset.
*
* @internal
*/
// @__NO_SIDE_EFFECTS__
export function _merge(value1: unknown, value2: unknown): MergeDataset {
// Continue if data type of values match
if (typeof value1 === typeof value2) {
// Return first value if both are equal
if (
_sameValueZero(value1, value2) ||
(value1 instanceof Date &&
value2 instanceof Date &&
_sameValueZero(+value1, +value2))
) {
return { value: value1 };
}
// Return deeply merged object
if (
value1 &&
value2 &&
value1.constructor === Object &&
value2.constructor === Object
) {
const nextValue = { ...value1 };
// Deeply merge entries of `value2` into `nextValue`
for (const key in value2) {
if (Object.prototype.hasOwnProperty.call(value1, key)) {
// @ts-expect-error
const dataset = _merge(value1[key], value2[key]);
// If dataset has issue, return it
if (dataset.issue) {
return dataset;
}
// Otherwise, replace merged entry
// @ts-expect-error
nextValue[key] = dataset.value;
// Otherwise, just add entry
} else {
// @ts-expect-error
nextValue[key] = value2[key];
}
}
// Return deeply merged object
return { value: nextValue };
}
// Return deeply merged array
if (Array.isArray(value1) && Array.isArray(value2)) {
// Continue if arrays have same length
if (value1.length === value2.length) {
const nextValue = [...value1];
// Merge items of `value2` into `nextValue`
for (let index = 0; index < value1.length; index++) {
const dataset = _merge(value1[index], value2[index]);
// If dataset has issue, return it
if (dataset.issue) {
return dataset;
}
// Otherwise, replace merged items
nextValue[index] = dataset.value;
}
// Return deeply merged array
return { value: nextValue };
}
}
}
// Otherwise, return that values can't be merged
return { issue: true };
}