Skip to content

Commit cf79677

Browse files
committed
Default values for nested discriminated unions didn't work.
Fixes #519
1 parent 6a2f286 commit cf79677

File tree

3 files changed

+53
-13
lines changed

3 files changed

+53
-13
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ Headlines: Added, Changed, Deprecated, Removed, Fixed, Security
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.21.1] - 2024-12-04
9+
10+
### Fixed
11+
12+
- Default values for nested discriminated unions didn't work.
13+
814
## [2.21.0] - 2024-12-01
915

1016
### Fixed

src/lib/errors.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,14 +286,9 @@ export function replaceInvalidDefaults<T extends Record<string, unknown>>(
286286
}
287287

288288
const fieldType = pathTypes.value ?? defaultType;
289-
if (!fieldType) {
290-
throw new SchemaError(
291-
'No default value specified for field (can be undefined, but must be explicit)',
292-
currentPath
293-
);
289+
if (fieldType) {
290+
Data_setValue(currentPath, Types_correctValue(dataValue, defValue, fieldType));
294291
}
295-
296-
Data_setValue(currentPath, Types_correctValue(dataValue, defValue, fieldType));
297292
}
298293
}
299294

src/tests/zodUnion.test.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import type { ValidationAdapter } from '$lib/adapters/adapters.js';
1+
import type { Infer, ValidationAdapter } from '$lib/adapters/adapters.js';
22
import { zod } from '$lib/adapters/zod.js';
33
import { superValidate } from '$lib/superValidate.js';
44
import { stringify } from 'devalue';
5-
import { describe, expect, test } from 'vitest';
5+
import { assert, describe, expect, test } from 'vitest';
66
import { z } from 'zod';
77

8-
async function validate(
9-
data: unknown,
10-
schema: ValidationAdapter<Record<string, unknown>>,
8+
async function validate<T extends Record<string, unknown>>(
9+
data: T,
10+
schema: ValidationAdapter<T>,
1111
strict = false
1212
) {
1313
const formInput = new FormData();
@@ -35,10 +35,49 @@ describe('Default discriminated union values 1', () => {
3535
});
3636

3737
test('Union with schema 2', async () => {
38-
const form = await validate({ type: 'extra' }, zod(schema), true);
38+
const form = await validate({ type: 'extra' } as Infer<typeof schema>, zod(schema), true);
3939
expect(form.valid).toBe(false);
4040
expect(form.data).toEqual({ type: 'extra', options: [] });
4141
});
42+
43+
test('Nested discriminated union with default value', async () => {
44+
const nested = z.object({
45+
addresses: z.object({
46+
additional: z
47+
.discriminatedUnion('type', [
48+
z.object({
49+
type: z.literal('poBox'),
50+
name: z.string().min(1, 'min len').max(10, 'max len')
51+
}),
52+
z.object({
53+
type: z.literal('none')
54+
})
55+
])
56+
.default({
57+
type: 'none'
58+
})
59+
})
60+
});
61+
62+
const form1 = await superValidate(zod(nested));
63+
expect(form1.data.addresses.additional).toEqual({ type: 'none' });
64+
65+
const form2 = await validate(
66+
{
67+
addresses: {
68+
additional: {
69+
type: 'poBox',
70+
name: '#123'
71+
}
72+
}
73+
},
74+
zod(nested)
75+
);
76+
77+
expect(form2.valid).toBe(true);
78+
assert(form2.data.addresses.additional?.type === 'poBox');
79+
expect(form2.data.addresses.additional.name).toBe('#123');
80+
});
4281
});
4382

4483
describe('Default discriminated union values 2', () => {

0 commit comments

Comments
 (0)