Skip to content

Commit e03349b

Browse files
committed
additional handlers config
1 parent cdc4053 commit e03349b

File tree

1 file changed

+41
-41
lines changed

1 file changed

+41
-41
lines changed

index.ts

+41-41
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,61 @@
1-
export type TypedPathKey = string | symbol | number;
1+
function pathToString(path: string[]): string {
2+
return path.reduce((current, next) => {
3+
if (+next === +next) {
4+
current += `[${next}]`;
5+
} else {
6+
current += current === '' ? `${next}` : `.${next}`;
7+
}
28

3-
export type TypedPathNode<T> = {
4-
$path: string;
5-
$raw: TypedPathKey[];
6-
};
9+
return current;
10+
}, '');
11+
}
12+
13+
export type TypedPathKey = string | symbol | number;
714

815
export type TypedPathFunction<T> = (...args: any[]) => T;
916

10-
export type TypedPathWrapper<T> = (T extends Array<infer Z>
17+
export type TypedPathHandlersConfig = Record<string, <T extends TypedPathHandlersConfig = Record<never, never>>(path: string[], additionalHandlers?: T) => any>;
18+
19+
const defaultHandlersConfig = {
20+
$path: (path: string[]) => pathToString(path),
21+
$raw: (path: string[]) => path,
22+
toString: (path: string[]) => () => pathToString(path),
23+
[Symbol.toStringTag]: (path: string[]) => () => pathToString(path),
24+
valueOf: (path: string[]) => () => pathToString(path),
25+
}
26+
27+
export type TypedPathHandlers<T extends TypedPathHandlersConfig> = {
28+
[key in keyof T]: ReturnType<T[key]>;
29+
};
30+
31+
export type TypedPathWrapper<T, TPH extends TypedPathHandlers<Record<never, never>>> = (T extends Array<infer Z>
1132
? {
12-
[index: number]: TypedPathWrapper<Z>;
33+
[index: number]: TypedPathWrapper<Z, TPH>;
1334
}
1435
: T extends TypedPathFunction<infer RET>
1536
? {
16-
(): TypedPathWrapper<RET>;
37+
(): TypedPathWrapper<RET, TPH>;
1738
} & {
18-
[P in keyof RET]: TypedPathWrapper<RET[P]>;
39+
[P in keyof RET]: TypedPathWrapper<RET[P], TPH>;
1940
}
2041
: {
21-
[P in keyof T]: TypedPathWrapper<T[P]>;
42+
[P in keyof T]: TypedPathWrapper<T[P], TPH>;
2243
}
23-
) & TypedPathNode<T>;
24-
25-
const toStringMethods: (string | symbol | number)[] = [
26-
'toString',
27-
Symbol.toStringTag,
28-
'valueOf'
29-
];
44+
) & TypedPathHandlers<TPH>;
3045

31-
function pathToString(path: string[]): string {
32-
return path.reduce((current, next) => {
33-
if (+next === +next) {
34-
current += `[${next}]`;
35-
} else {
36-
current += current === '' ? `${next}` : `.${next}`;
37-
}
38-
39-
return current;
40-
}, '');
41-
}
42-
43-
export function typedPath<T>(path: string[] = []): TypedPathWrapper<T> {
44-
return <TypedPathWrapper<T>>new Proxy({}, {
46+
export function typedPath<T, K extends TypedPathHandlersConfig = Record<never, never>>(path: string[] = [], additionalHandlers?: K): TypedPathWrapper<T, K & typeof defaultHandlersConfig> {
47+
return <TypedPathWrapper<T, K & typeof defaultHandlersConfig>>new Proxy({}, {
4548
get(target: T, name: TypedPathKey) {
46-
if (name === '$path') {
47-
return pathToString(path);
48-
}
49-
50-
if (name === '$raw') {
51-
return path;
52-
}
49+
const handlersConfig: TypedPathHandlersConfig = { ...(additionalHandlers ?? {}), ...defaultHandlersConfig };
5350

54-
if (toStringMethods.includes(name)) {
55-
return () => pathToString(path);
51+
const keys: (keyof typeof handlersConfig)[] = Object.keys(handlersConfig);
52+
for (const key of keys) {
53+
if (key === name) {
54+
return handlersConfig[key](path, additionalHandlers);
55+
}
5656
}
5757

58-
return typedPath([...path, name.toString()]);
58+
return typedPath([...path, name.toString()], additionalHandlers);
5959
}
6060
});
6161
}

0 commit comments

Comments
 (0)