-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDeepStrictAssert.ts
More file actions
60 lines (52 loc) · 2.08 KB
/
Copy pathDeepStrictAssert.ts
File metadata and controls
60 lines (52 loc) · 2.08 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
import { DeepStrictObjectKeys } from '../types/DeepStrictObjectKeys';
import { DeepStrictPick } from '../types/DeepStrictPick';
/**
* @title Runtime Function for Type-Safe Deep Property Extraction.
*
* A curried function that takes an object and returns a picker function.
* The picker function accepts a dot-notation key path and returns a new object
* containing only the specified nested property, preserving the original structure.
*
* This is the runtime counterpart of the {@link DeepStrictPick} type.
*
* @deprecated Use {@link deepStrictPick} instead. This curried form will be removed in a future version.
*
* @template T - The object type of the input
* @param input - The source object to extract properties from
* @returns A function that accepts a key path `K` and returns the deeply-picked result
*
* @example
* ```ts
* const result = deepStrictAssert({ a: { b: 1, c: 2 } })('a.b');
* // result: { a: { b: 1 } }
* ```
*/
export const deepStrictAssert =
<T extends object>(input: T) =>
<K extends DeepStrictObjectKeys<T>>(key: K): DeepStrictPick<T, K> => {
const keys = key.split(/(?:\[\*\])?\./g).filter(Boolean);
const traverse = (input: Record<string, any> | Record<string, any>[], keys: string[]): any => {
const [first, ...rest] = keys;
if (input instanceof Array) {
const elements = input.map((element) => {
if (first in element) {
if (typeof element[first] === 'object' && element[first] !== null && rest.length > 0) {
return { [first]: traverse(element[first], rest) };
}
return { [first]: element[first] };
}
return element;
});
return elements;
} else {
if (first in input) {
if (typeof input[first] === 'object' && input[first] !== null && rest.length > 0) {
return { [first]: traverse(input[first], rest) };
}
return { [first]: input[first] };
}
throw new Error(`input doesn\'t have key: ${first}`);
}
};
return traverse(input, keys) as DeepStrictPick<T, K>;
};