-
Notifications
You must be signed in to change notification settings - Fork 39
/
index.ts
99 lines (65 loc) · 2.1 KB
/
index.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
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
97
98
99
module.exports = exports = main
export default main
export function main(clone: boolean, ...items: any[]): any
export function main(...items: any[]): any
export function main(...items: any[]) {
return merge(...items)
}
main.clone = clone
main.isPlainObject = isPlainObject
main.recursive = recursive
export function merge(clone: boolean, ...items: any[]): any
export function merge(...items: any[]): any
export function merge(...items: any[]) {
return _merge(items[0] === true, false, items)
}
export function recursive(clone: boolean, ...items: any[]): any
export function recursive(...items: any[]): any
export function recursive(...items: any[]) {
return _merge(items[0] === true, true, items)
}
export function clone<T>(input: T): T {
if (Array.isArray(input)) {
const output = []
for (let index = 0; index < input.length; ++index)
output.push(clone(input[index]))
return output as any
} else if (isPlainObject(input)) {
const output: any = {}
for (let index in input)
output[index] = clone(input[index])
return output as any
} else {
return input
}
}
export function isPlainObject(input: any): input is Object {
return input && typeof input === 'object' && !Array.isArray(input)
}
function _recursiveMerge(base: any, extend: any) {
if (!isPlainObject(base))
return extend
for (const key in extend) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
base[key] = (isPlainObject(base[key]) && isPlainObject(extend[key])) ?
_recursiveMerge(base[key], extend[key]) :
extend[key]
}
return base
}
function _merge(isClone: boolean, isRecursive: boolean, items: any[]) {
let result
if (isClone || !isPlainObject(result = items.shift()))
result = {}
for (let index = 0; index < items.length; ++index) {
const item = items[index]
if (!isPlainObject(item))
continue
for (const key in item) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
const value = isClone ? clone(item[key]) : item[key]
result[key] = isRecursive ? _recursiveMerge(result[key], value) : value
}
}
return result
}