Skip to content

Commit a84df0b

Browse files
committed
WIP: Only array _errors, not all objects
1 parent ff0db74 commit a84df0b

File tree

2 files changed

+55
-26
lines changed

2 files changed

+55
-26
lines changed

src/lib/stringPath.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,46 @@ export type StringPath<T extends object> = NonNullable<T> extends (infer U)[]
5959
}[keyof T]
6060
: never;
6161

62-
export type StringPathLeaves<T extends object> =
63-
NonNullable<T> extends (infer U)[]
64-
? NonNullable<U> extends object
65-
? `[${number}]${NonNullable<U> extends unknown[]
66-
? ''
67-
: '.'}${StringPathLeaves<NonNullable<U>> & string}`
68-
: `[${number}]`
69-
: NonNullable<T> extends object
62+
type ArrField<Arr extends string, K> = Arr extends never
63+
? never
64+
: K extends string
65+
? `${K}.${Arr}`
66+
: never;
67+
68+
export type StringPathLeaves<
69+
T extends object,
70+
Arr extends string = never
71+
> = NonNullable<T> extends (infer U)[]
72+
? NonNullable<U> extends object
7073
?
71-
| {
72-
// Same as FilterObjects but inlined for better intellisense
73-
[K in keyof T]: NonNullable<T[K]> extends object
74-
? NonNullable<T[K]> extends Date | Set<unknown>
75-
? K
76-
: never
77-
: K;
78-
}[keyof T]
79-
| {
80-
[K in keyof T]-?: K extends string
81-
? NonNullable<T[K]> extends object
82-
? `${K}${NonNullable<T[K]> extends unknown[]
83-
? ''
84-
: '.'}${StringPathLeaves<NonNullable<T[K]>> & string}`
85-
: never
86-
: never;
87-
}[keyof T]
88-
: never;
74+
| `[${number}].${Arr}`
75+
| `[${number}]${NonNullable<U> extends unknown[]
76+
? ''
77+
: '.'}${StringPathLeaves<NonNullable<U>, Arr> & string}`
78+
: `[${number}]`
79+
: NonNullable<T> extends object
80+
?
81+
| {
82+
// Same as FilterObjects but inlined for better intellisense
83+
[K in keyof T]: NonNullable<T[K]> extends object
84+
? NonNullable<T[K]> extends Date | Set<unknown>
85+
? K
86+
: never
87+
: K;
88+
}[keyof T]
89+
| {
90+
[K in keyof T]-?: K extends string
91+
? NonNullable<T[K]> extends object
92+
?
93+
| ArrField<Arr, K>
94+
| `${K}${NonNullable<T[K]> extends unknown[]
95+
? ''
96+
: '.'}${StringPathLeaves<NonNullable<T[K]>, Arr> &
97+
string}`
98+
: never
99+
: never;
100+
}[keyof T]
101+
: never;
89102

90103
export type FormPathType<T, P extends string> = P extends keyof T
91104
? T[P]

src/paths.test-d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ test('StringPathLeaves', () => {
9292

9393
// obj.ok should exist even though it's an object (Date)
9494
const p: StringPathLeaves<typeof o> = 'test[3]';
95+
96+
type ExtraLeaves = StringPathLeaves<typeof o, '_errors'>;
97+
98+
const a1: ExtraLeaves = 'test._errors';
99+
const a2: ExtraLeaves = 'obj.arr._errors';
100+
// @ts-expect-error incorrect path
101+
const a3: ExtraLeaves = 'obj.name._errors';
102+
// @ts-expect-error incorrect path
103+
const a4: ExtraLeaves = 'obj._errors';
104+
// @ts-expect-error incorrect path
105+
const a5: ExtraLeaves = 'obj.arr[2]._errors';
106+
const a6: ExtraLeaves = 'obj.arr[2]';
107+
const a7: ExtraLeaves = 'obj.next._errors';
108+
const a8: ExtraLeaves = 'obj.next[1].level';
109+
// @ts-expect-error incorrect path
110+
const a9: ExtraLeaves = 'obj.next[1]._errors';
95111
});
96112

97113
test('Objects with sets', () => {

0 commit comments

Comments
 (0)