-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdiff.ts
57 lines (51 loc) · 1.97 KB
/
diff.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
import { isDictLike } from "https://lib.deno.dev/x/is_like@latest/index.js";
import isEmpty from "./isEmpty.ts";
import isVoid from "./isVoid.ts";
/**
* Creates an array that contains the difference set between `origin` and
* `input`;
*/
export default function diff<T>(origin: T[], input: T[]): T[];
/**
* Evaluates the differences between `origin` and `input`, if a property exists
* in both objects and the values are not equal, the `input` one will be taken.
*
* NOTE: This function treats all void values equal and will not differ them.
*/
export default function diff<T, U>(origin: T, input: U): Diff<T, U>;
export default function diff<T, U>(origin: T, input: U, deep: true): DeepPartial<T & U>;
export default function diff(origin: any, input: any, deep = false) {
if (Array.isArray(origin) && Array.isArray(input)) {
return [
...input.filter(value => !origin.includes(value)),
...origin.filter(value => !input.includes(value))
];
} else if (isDictLike(origin) && isDictLike(input)) {
let keys = Reflect.ownKeys(input);
let _keys = Reflect.ownKeys(origin);
let result: any = {};
keys.forEach(key => {
if (origin[key] !== input[key] &&
!(isVoid(origin[key]) && isVoid(input[key])) // ignore void values
) {
if (deep &&
typeof origin[key] === "object" && origin[key] !== null &&
typeof input[key] === "object" && input[key] !== null
) {
let _result = diff(origin[key], input[key], deep);
if (!isEmpty(_result)) {
result[key] = _result;
}
} else {
result[key] = input[key];
}
}
});
_keys.forEach(key => {
keys.includes(key) || (result[key] = origin[key]);
});
return result;
} else {
return input;
}
}