/
set.ts
70 lines (60 loc) 路 1.7 KB
/
set.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
export function set<T extends Record<string, unknown>>(
object: T,
path: string[],
value: unknown
): (T & { [p: string]: unknown }) | T {
const { decomposedPath, base } = decomposePath(path);
if (base === undefined) {
return object;
}
// assign an empty object in order to spread object
assignEmpty(object, base);
// Determine if there is still layers to traverse
value =
decomposedPath.length <= 1
? value
: set(
object[base] as Record<string, unknown>,
decomposedPath.slice(1),
value
);
return Object.assign(object, { [base]: value });
}
export function setMutate<T extends Record<string, unknown>>(
object: T,
path: string[],
value: unknown
): void {
const { decomposedPath, base } = decomposePath(path);
if (base === undefined) {
return;
}
// assign an empty object in order to spread object
assignEmpty(object, base);
// Determine if there is still layers to traverse
if (decomposedPath.length <= 1) {
(object as Record<string, unknown>)[base] = value;
} else {
setMutate(
object[base] as Record<string, unknown>,
decomposedPath.slice(1),
value
);
}
}
function decomposePath(path: string[]): {
decomposedPath: string[];
base: string;
} {
if (path.length < 1) {
return { base: '', decomposedPath: [] };
}
const decomposedPath = path;
const base = path[0];
return { base, decomposedPath };
}
function assignEmpty(obj: Record<string, unknown>, base: string) {
if (!obj.hasOwnProperty(base)) {
obj[base] = {};
}
}