Skip to content

Commit 94ae254

Browse files
committed
partialByAsync
1 parent 8ea4eae commit 94ae254

File tree

13 files changed

+716
-5
lines changed

13 files changed

+716
-5
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './partialBy.ts';
2+
export * from './partialByAsync.ts';
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
import { describe, expectTypeOf, test } from 'vitest';
2+
import {
3+
boolean,
4+
type BooleanIssue,
5+
nullishAsync,
6+
number,
7+
type NumberIssue,
8+
objectAsync,
9+
type ObjectIssue,
10+
objectWithRestAsync,
11+
type ObjectWithRestIssue,
12+
optionalAsync,
13+
string,
14+
type StringIssue,
15+
} from '../../schemas/index.ts';
16+
import type { BaseHKTable, HKTImplementation } from '../../types/hkt.ts';
17+
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts';
18+
import {
19+
partialByAsync,
20+
type PartialByModifierAsyncHKT,
21+
type SchemaWithPartialByAsync,
22+
} from './partialByAsync.ts';
23+
24+
type ModifierImpl = HKTImplementation<BaseHKTable<PartialByModifierAsyncHKT>>;
25+
26+
describe('partialByAsync', () => {
27+
const entries = {
28+
key1: string(),
29+
key2: number(),
30+
key3: string(),
31+
key4: nullishAsync(number(), async () => 123),
32+
};
33+
34+
describe('objectAsync', () => {
35+
const wrapped = objectAsync(entries);
36+
type Wrapped = typeof wrapped;
37+
type Schema1<TModifier extends ModifierImpl> = SchemaWithPartialByAsync<
38+
Wrapped,
39+
ReturnType<TModifier>,
40+
undefined
41+
>;
42+
type Schema2<TModifier extends ModifierImpl> = SchemaWithPartialByAsync<
43+
Wrapped,
44+
ReturnType<TModifier>,
45+
['key1', 'key3']
46+
>;
47+
48+
describe('should return schema objectAsync', () => {
49+
test('with modified keys', () => {
50+
expectTypeOf(partialByAsync(wrapped, optionalAsync)).toEqualTypeOf<
51+
Schema1<typeof optionalAsync>
52+
>();
53+
expectTypeOf(partialByAsync(wrapped, nullishAsync)).toEqualTypeOf<
54+
Schema1<typeof nullishAsync>
55+
>();
56+
});
57+
test('with specific keys', () => {
58+
expectTypeOf(
59+
partialByAsync(wrapped, optionalAsync, ['key1', 'key3'])
60+
).toEqualTypeOf<Schema2<typeof optionalAsync>>();
61+
expectTypeOf(
62+
partialByAsync(wrapped, nullishAsync, ['key1', 'key3'])
63+
).toEqualTypeOf<Schema2<typeof nullishAsync>>();
64+
});
65+
66+
describe('should infer correct types', () => {
67+
test('of input', () => {
68+
expectTypeOf<
69+
InferInput<Schema1<typeof optionalAsync>>
70+
>().toEqualTypeOf<{
71+
key1?: string;
72+
key2?: number;
73+
key3?: string;
74+
key4?: number | null;
75+
}>();
76+
expectTypeOf<
77+
InferInput<Schema1<typeof nullishAsync>>
78+
>().toEqualTypeOf<{
79+
key1?: string | null;
80+
key2?: number | null;
81+
key3?: string | null;
82+
key4?: number | null;
83+
}>();
84+
expectTypeOf<
85+
InferInput<Schema2<typeof optionalAsync>>
86+
>().toEqualTypeOf<{
87+
key1?: string;
88+
key2: number;
89+
key3?: string;
90+
key4?: number | null | undefined;
91+
}>();
92+
expectTypeOf<
93+
InferInput<Schema2<typeof nullishAsync>>
94+
>().toEqualTypeOf<{
95+
key1?: string | null | undefined;
96+
key2: number;
97+
key3?: string | null | undefined;
98+
key4?: number | null | undefined;
99+
}>();
100+
});
101+
102+
test('of output', () => {
103+
expectTypeOf<
104+
InferOutput<Schema1<typeof optionalAsync>>
105+
>().toEqualTypeOf<{
106+
key1?: string;
107+
key2?: number;
108+
key3?: string;
109+
key4?: number;
110+
}>();
111+
expectTypeOf<
112+
InferOutput<Schema1<typeof nullishAsync>>
113+
>().toEqualTypeOf<{
114+
key1?: string | null;
115+
key2?: number | null;
116+
key3?: string | null;
117+
key4?: number | null;
118+
}>();
119+
expectTypeOf<
120+
InferOutput<Schema2<typeof optionalAsync>>
121+
>().toEqualTypeOf<{
122+
key1?: string;
123+
key2: number;
124+
key3?: string;
125+
key4: number;
126+
}>();
127+
expectTypeOf<
128+
InferOutput<Schema2<typeof nullishAsync>>
129+
>().toEqualTypeOf<{
130+
key1?: string | null;
131+
key2: number;
132+
key3?: string | null;
133+
key4: number;
134+
}>();
135+
});
136+
137+
test('of issue', () => {
138+
expectTypeOf<
139+
InferIssue<Schema1<typeof optionalAsync>>
140+
>().toEqualTypeOf<ObjectIssue | StringIssue | NumberIssue>();
141+
expectTypeOf<
142+
InferIssue<Schema1<typeof nullishAsync>>
143+
>().toEqualTypeOf<ObjectIssue | StringIssue | NumberIssue>();
144+
expectTypeOf<
145+
InferIssue<Schema2<typeof optionalAsync>>
146+
>().toEqualTypeOf<ObjectIssue | StringIssue | NumberIssue>();
147+
expectTypeOf<
148+
InferIssue<Schema2<typeof nullishAsync>>
149+
>().toEqualTypeOf<ObjectIssue | StringIssue | NumberIssue>();
150+
});
151+
});
152+
});
153+
});
154+
describe('objectWithRestAsync', () => {
155+
const rest = boolean();
156+
const wrapped = objectWithRestAsync(entries, rest);
157+
type Wrapped = typeof wrapped;
158+
type Schema1<TModifier extends ModifierImpl> = SchemaWithPartialByAsync<
159+
Wrapped,
160+
ReturnType<TModifier>,
161+
undefined
162+
>;
163+
type Schema2<TModifier extends ModifierImpl> = SchemaWithPartialByAsync<
164+
Wrapped,
165+
ReturnType<TModifier>,
166+
['key1', 'key3']
167+
>;
168+
169+
describe('should return schema objectWithRestAsync', () => {
170+
test('with modified keys', () => {
171+
expectTypeOf(partialByAsync(wrapped, optionalAsync)).toEqualTypeOf<
172+
Schema1<typeof optionalAsync>
173+
>();
174+
expectTypeOf(partialByAsync(wrapped, nullishAsync)).toEqualTypeOf<
175+
Schema1<typeof nullishAsync>
176+
>();
177+
});
178+
test('with specific keys', () => {
179+
expectTypeOf(
180+
partialByAsync(wrapped, optionalAsync, ['key1', 'key3'])
181+
).toEqualTypeOf<Schema2<typeof optionalAsync>>();
182+
expectTypeOf(
183+
partialByAsync(wrapped, nullishAsync, ['key1', 'key3'])
184+
).toEqualTypeOf<Schema2<typeof nullishAsync>>();
185+
});
186+
187+
describe('should infer correct types', () => {
188+
test('of input', () => {
189+
expectTypeOf<
190+
InferInput<Schema1<typeof optionalAsync>>
191+
>().toEqualTypeOf<
192+
{
193+
key1?: string;
194+
key2?: number;
195+
key3?: string;
196+
key4?: number | null;
197+
} & {
198+
[key: string]: boolean;
199+
}
200+
>();
201+
expectTypeOf<
202+
InferInput<Schema1<typeof nullishAsync>>
203+
>().toEqualTypeOf<
204+
{
205+
key1?: string | null | undefined;
206+
key2?: number | null | undefined;
207+
key3?: string | null | undefined;
208+
key4?: number | null | undefined;
209+
} & {
210+
[key: string]: boolean;
211+
}
212+
>();
213+
expectTypeOf<
214+
InferInput<Schema2<typeof optionalAsync>>
215+
>().toEqualTypeOf<
216+
{
217+
key1?: string;
218+
key2: number;
219+
key3?: string;
220+
key4?: number | null;
221+
} & {
222+
[key: string]: boolean;
223+
}
224+
>();
225+
expectTypeOf<
226+
InferInput<Schema2<typeof nullishAsync>>
227+
>().toEqualTypeOf<
228+
{
229+
key1?: string | null | undefined;
230+
key2: number;
231+
key3?: string | null | undefined;
232+
key4?: number | null;
233+
} & {
234+
[key: string]: boolean;
235+
}
236+
>();
237+
});
238+
239+
test('of output', () => {
240+
expectTypeOf<
241+
InferOutput<Schema1<typeof optionalAsync>>
242+
>().toEqualTypeOf<
243+
{
244+
key1?: string;
245+
key2?: number;
246+
key3?: string;
247+
key4?: number;
248+
} & {
249+
[key: string]: boolean;
250+
}
251+
>();
252+
expectTypeOf<
253+
InferOutput<Schema1<typeof nullishAsync>>
254+
>().toEqualTypeOf<
255+
{
256+
key1?: string | null;
257+
key2?: number | null;
258+
key3?: string | null;
259+
key4?: number | null;
260+
} & {
261+
[key: string]: boolean;
262+
}
263+
>();
264+
expectTypeOf<
265+
InferOutput<Schema2<typeof optionalAsync>>
266+
>().toEqualTypeOf<
267+
{
268+
key1?: string;
269+
key2: number;
270+
key3?: string;
271+
key4: number;
272+
} & {
273+
[key: string]: boolean;
274+
}
275+
>();
276+
expectTypeOf<
277+
InferOutput<Schema2<typeof nullishAsync>>
278+
>().toEqualTypeOf<
279+
{
280+
key1?: string | null;
281+
key2: number;
282+
key3?: string | null;
283+
key4: number;
284+
} & {
285+
[key: string]: boolean;
286+
}
287+
>();
288+
});
289+
290+
test('of issue', () => {
291+
expectTypeOf<
292+
InferIssue<Schema1<typeof optionalAsync>>
293+
>().toEqualTypeOf<
294+
ObjectWithRestIssue | StringIssue | NumberIssue | BooleanIssue
295+
>();
296+
expectTypeOf<
297+
InferIssue<Schema1<typeof nullishAsync>>
298+
>().toEqualTypeOf<
299+
ObjectWithRestIssue | StringIssue | NumberIssue | BooleanIssue
300+
>();
301+
expectTypeOf<
302+
InferIssue<Schema2<typeof optionalAsync>>
303+
>().toEqualTypeOf<
304+
ObjectWithRestIssue | StringIssue | NumberIssue | BooleanIssue
305+
>();
306+
expectTypeOf<
307+
InferIssue<Schema2<typeof nullishAsync>>
308+
>().toEqualTypeOf<
309+
ObjectWithRestIssue | StringIssue | NumberIssue | BooleanIssue
310+
>();
311+
});
312+
});
313+
});
314+
});
315+
});

0 commit comments

Comments
 (0)