Skip to content

Commit 275ebef

Browse files
authored
Merge pull request #26 from kakasoo/kakasoo/deep-strict-flat
feat: add deepStrictPick runtime function
2 parents 30a9c2f + 4dc7b9b commit 275ebef

File tree

4 files changed

+396
-0
lines changed

4 files changed

+396
-0
lines changed

src/functions/DeepStrictAssert.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { DeepStrictPick } from '../types/DeepStrictPick';
1010
*
1111
* This is the runtime counterpart of the {@link DeepStrictPick} type.
1212
*
13+
* @deprecated Use {@link deepStrictPick} instead. This curried form will be removed in a future version.
14+
*
1315
* @template T - The object type of the input
1416
* @param input - The source object to extract properties from
1517
* @returns A function that accepts a key path `K` and returns the deeply-picked result

src/functions/DeepStrictPick.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { DeepStrictObjectKeys } from '../types/DeepStrictObjectKeys';
2+
import { DeepStrictPick } from '../types/DeepStrictPick';
3+
4+
/**
5+
* @title Runtime Function for Type-Safe Deep Property Picking.
6+
*
7+
* Takes an object and a dot-notation key path, and returns a new object
8+
* containing only the specified nested property, preserving the original structure.
9+
*
10+
* This is the runtime counterpart of the {@link DeepStrictPick} type.
11+
*
12+
* @template T - The object type of the input
13+
* @template K - The key path to pick
14+
* @param input - The source object to extract properties from
15+
* @param key - A dot-notation key path specifying which property to pick
16+
* @returns A new object containing only the picked property with its original structure
17+
*
18+
* @example
19+
* ```ts
20+
* const result = deepStrictPick({ a: { b: 1, c: 2 } }, 'a.b');
21+
* // result: { a: { b: 1 } }
22+
* ```
23+
*/
24+
export const deepStrictPick = <T extends object, K extends DeepStrictObjectKeys<T>>(
25+
input: T,
26+
key: K,
27+
): DeepStrictPick<T, K> => {
28+
const keys = key.split(/(?:\[\*\])?\./g).filter(Boolean);
29+
30+
const traverse = (input: Record<string, any> | Record<string, any>[], keys: string[]): any => {
31+
const [first, ...rest] = keys;
32+
33+
if (input instanceof Array) {
34+
const elements = input.map((element) => {
35+
if (first in element) {
36+
if (typeof element[first] === 'object' && element[first] !== null && rest.length > 0) {
37+
return { [first]: traverse(element[first], rest) };
38+
}
39+
40+
return { [first]: element[first] };
41+
}
42+
43+
return element;
44+
});
45+
46+
return elements;
47+
} else {
48+
if (first in input) {
49+
if (typeof input[first] === 'object' && input[first] !== null && rest.length > 0) {
50+
return { [first]: traverse(input[first], rest) };
51+
}
52+
return { [first]: input[first] };
53+
}
54+
55+
throw new Error(`input doesn\'t has key: ${first}`);
56+
}
57+
};
58+
59+
return traverse(input, keys) as DeepStrictPick<T, K>;
60+
};

src/functions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './DeepStrictAssert';
22
export * from './DeepStrictObjectKeys';
3+
export * from './DeepStrictPick';

0 commit comments

Comments
 (0)