Skip to content

Commit 301da51

Browse files
authored
fix(conform-zod): Zod v4 required field coercion (#1084)
1 parent 249901b commit 301da51

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@conform-to/zod': patch
3+
---
4+
5+
fix(conform-zod): Zod v4 required field coercion
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { describe, test, expect } from 'vitest';
2+
import { coerceFormValue } from '../../../coercion';
3+
import { z } from 'zod';
4+
import { getResult } from '../../../../tests/helpers/zod';
5+
6+
describe('coercion', () => {
7+
describe('required', () => {
8+
test('should pass required', () => {
9+
const schema = z
10+
.object({
11+
a: z.string().optional(),
12+
})
13+
.required();
14+
15+
expect(getResult(coerceFormValue(schema).safeParse({ a: '' }))).toEqual({
16+
success: false,
17+
error: {
18+
a: ['Required'],
19+
},
20+
});
21+
22+
expect(
23+
getResult(coerceFormValue(schema).safeParse({ a: 'string' })),
24+
).toEqual({
25+
success: true,
26+
data: {
27+
a: 'string',
28+
},
29+
});
30+
});
31+
});
32+
});

packages/conform-zod/v4/coercion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ export function enableTypeCoercion<Schema extends $ZodType>(
235235
),
236236
}) as $ZodType<unknown, {}>,
237237
);
238-
} else if (def.type === 'optional') {
238+
} else if (def.type === 'optional' || def.type === 'nonoptional') {
239239
schema = pipe(
240240
transform(options.stripEmptyValue),
241241
new constr({
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { describe, test, expect } from 'vitest';
2+
import { coerceFormValue } from '../../../coercion';
3+
import { z } from 'zod-v4';
4+
import { object, string, optional, required } from 'zod-v4/mini';
5+
import { getResult } from '../../../../tests/helpers/zod';
6+
7+
describe('coercion', () => {
8+
describe('required', () => {
9+
test('should pass required', () => {
10+
const schema = z
11+
.object({
12+
a: z.string().optional(),
13+
})
14+
.required();
15+
const schemaWithMini = required(
16+
object({
17+
a: optional(string()),
18+
}),
19+
);
20+
21+
expect(getResult(coerceFormValue(schema).safeParse({ a: '' }))).toEqual({
22+
success: false,
23+
error: {
24+
a: ['Invalid input'],
25+
},
26+
});
27+
expect(
28+
getResult(coerceFormValue(schemaWithMini).safeParse({ a: '' })),
29+
).toEqual({
30+
success: false,
31+
error: {
32+
a: ['Invalid input'],
33+
},
34+
});
35+
expect(
36+
getResult(coerceFormValue(schema).safeParse({ a: 'string' })),
37+
).toEqual({
38+
success: true,
39+
data: {
40+
a: 'string',
41+
},
42+
});
43+
expect(
44+
getResult(coerceFormValue(schemaWithMini).safeParse({ a: 'string' })),
45+
).toEqual({
46+
success: true,
47+
data: {
48+
a: 'string',
49+
},
50+
});
51+
});
52+
});
53+
});

0 commit comments

Comments
 (0)