forked from ciscoheat/sveltekit-superforms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpaths.test-d.ts
134 lines (115 loc) · 3.47 KB
/
paths.test-d.ts
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* eslint-disable @typescript-eslint/no-unused-vars */
import type {
StringPath,
FormPathType,
StringPathLeaves
} from '$lib/stringPath';
import { test } from 'vitest';
type Obj = {
name: string;
points: number;
scores: Date[][];
city: {
name: string;
};
tags:
| ({ id: number; name: string; parents: number[] } | null)[]
| undefined;
};
const i = 7 + 3;
type Test = StringPath<Obj>;
test('StringPath', () => {
const a1: Test = 'name';
const a2: Test = 'city';
const a3: Test = 'tags';
const a4: Test = 'city.name';
const a5: Test = 'tags[3]';
const a6: Test = 'tags[3].name';
const a7: Test = 'scores[3][4]';
// @ts-expect-error incorrect path
const n8: Test = 'city[3]';
// @ts-expect-error incorrect path
const n7: Test = 'city.nope';
// @ts-expect-error incorrect path
const n9: Test = 'tags[4].nope';
// @ts-expect-error incorrect path
const n0: Test = 'nope';
});
function checkPath<T = never>() {
return function <U extends string = string>(path: U): FormPathType<T, U> {
return path as FormPathType<T, U>;
};
}
const checkObj = checkPath<Obj>();
test('StringPathType', () => {
const a = checkObj(`tags[${i + 3}].name`); // string
const b = checkObj(`scores[${i + 3}][0]`); // Date
const t0: FormPathType<Obj, 'name'> = 'string';
const t1: FormPathType<Obj, 'points'> = 123;
const t2: FormPathType<Obj, 'city'> = { name: 'London' };
const t3: FormPathType<Obj, 'tags'> = [
{ id: 123, name: 'Test', parents: [] }
];
const t4: FormPathType<Obj, 'tags[0]'> = {
id: 123,
name: 'Test',
parents: [1]
};
const t5: FormPathType<Obj, 'tags[0].name'> = 'string';
const t6: FormPathType<Obj, `tags[5].id`> = 123;
// @ts-expect-error incorrect path
const n1: FormPathType<Obj, 'city[2]'> = 'never';
// @ts-expect-error incorrect path
const n2: FormPathType<Obj, 'nope incorrect'> = 'never';
});
test('StringPathLeaves', () => {
const o = {
test: [1, 2, 3],
test2: [
[{ date: new Date() }],
[{ date: new Date() }, { date: new Date() }]
],
name: 'name',
other: [{ test: 'a', ok: 123 }, { test: 'b' }],
obj: {
ok: new Date('2023-05-29'),
arr: [1, 2, 3],
test: '1231231',
next: [{ level: 1 }, { level: 2 }]
}
};
// obj.ok should exist even though it's an object (Date)
const p: StringPathLeaves<typeof o> = 'test[3]';
type ExtraLeaves = StringPathLeaves<typeof o, '_errors'>;
const a1: ExtraLeaves = 'test._errors';
const a2: ExtraLeaves = 'obj.arr._errors';
// @ts-expect-error incorrect path
const a3: ExtraLeaves = 'obj.name._errors';
// @ts-expect-error incorrect path
const a4: ExtraLeaves = 'obj._errors';
// @ts-expect-error incorrect path
const a5: ExtraLeaves = 'obj.arr[2]._errors';
const a6: ExtraLeaves = 'obj.arr[2]';
const a7: ExtraLeaves = 'obj.next._errors';
const a8: ExtraLeaves = 'obj.next[1].level';
// @ts-expect-error incorrect path
const a9: ExtraLeaves = 'obj.next[1]._errors';
});
test('Objects with sets', () => {
type SetObj = {
numbers: {
set: Set<number>;
};
};
type SetTest = StringPath<SetObj>;
const a1: SetTest = 'numbers';
const a2: SetTest = 'numbers.set';
// @ts-expect-error incorrect path
const a3: SetTest = 'numbers.set.size';
type SetLeaves = StringPathLeaves<SetObj>;
// @ts-expect-error incorrect path
const b1: SetLeaves = 'numbers';
const b2: SetLeaves = 'numbers.set';
// @ts-expect-error incorrect path
const b3: SetTest = 'numbers.set.size';
});