Skip to content

Commit 216b546

Browse files
committed
Fixed recursive type checking crash.
1 parent 6b835e0 commit 216b546

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

src/lib/stringPath.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ export function mergePath(path: (string | number | symbol)[]) {
2323
*/
2424
export type FormPath<T extends object> =
2525
| (string & StringPath<T>)
26-
| FormPathLeaves<T>;
26+
| FormPathLeaves<T>
27+
| FormPathArrays<T>;
2728

2829
/**
2930
* List paths in an object as string accessors, but only with non-objects as accessible properties.
@@ -34,8 +35,29 @@ export type FormPathLeaves<T extends object> = string & StringPathLeaves<T>;
3435
/**
3536
* List all arrays in an object as string accessors.
3637
*/
37-
export type FormPathArrays<T extends object> = string &
38-
Exclude<StringPath<T, true>, FormPathLeaves<T>>;
38+
export type FormPathArrays<T extends object> = string & StringPathArrays<T>;
39+
40+
export type StringPathArrays<T extends object, Path extends string = ''> = {
41+
[K in Extract<keyof T, string>]: NonNullable<T[K]> extends
42+
| Date
43+
| Set<unknown>
44+
? never
45+
: NonNullable<T[K]> extends (infer U)[]
46+
?
47+
| `${Path}${Path extends '' ? '' : '.'}${K}`
48+
| StringPathArrays<
49+
NonNullable<U>,
50+
`${Path}${Path extends '' ? '' : '.'}${K}[${number}]`
51+
>
52+
: NonNullable<T[K]> extends object
53+
? StringPathArrays<
54+
NonNullable<T[K]>,
55+
`${Path}${Path extends '' ? '' : '.'}${K}`
56+
>
57+
: NonNullable<T> extends unknown[]
58+
? Path
59+
: never;
60+
}[Extract<keyof T, string>];
3961

4062
export type StringPath<
4163
T extends object,

src/paths.test-d.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type {
66
StringPathLeaves
77
} from '$lib/stringPath';
88
import { test } from 'vitest';
9-
import type { z } from 'zod';
109

1110
type Obj = {
1211
name: string;
@@ -21,6 +20,22 @@ type Obj = {
2120
names: string[];
2221
};
2322

23+
type FormData = {
24+
field1: string[] | null;
25+
field2: {
26+
subField1: number[] | null;
27+
subField2: {
28+
nestedField: boolean[] | null;
29+
} | null;
30+
} | null;
31+
field3: {
32+
nestedArray: {
33+
innerArray: string[] | null;
34+
}[];
35+
};
36+
};
37+
type FormDataArrays = FormPathArrays<FormData>;
38+
2439
const i = 7 + 3;
2540

2641
type Test = StringPath<Obj>;

src/routes/tests/array-component/AutoComplete.svelte

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<script lang="ts" generics="T extends AnyZodObject">
77
import type { z } from 'zod';
8-
import type { ZodValidation, FormPath, FormPathArrays } from '$lib';
8+
import type { ZodValidation, FormPathArrays } from '$lib';
99
import type { Writable } from 'svelte/store';
1010
import { fieldProxy, type SuperForm } from '$lib/client';
1111
@@ -15,10 +15,7 @@
1515
export let label = '';
1616
1717
const value = fieldProxy(form.form, field) as Writable<unknown[]>;
18-
const errors = fieldProxy(
19-
form.errors,
20-
`${field}._errors` as FormPath<z.infer<T>>
21-
);
18+
const errors = fieldProxy(form.errors, `${field}._errors` as any);
2219
</script>
2320

2421
{#if label}<label for={field}>{label}</label>{/if}

0 commit comments

Comments
 (0)