如何为Zod表单可选字段设置非空时的验证规则?
Zod 可选字段验证配置方案
问题根源:你的.optional()仅允许字段不存在(值为undefined),但当用户提交空字符串时,z.string()默认会拒绝空值,导致验证失败,看起来像是必填项。要实现「字段可留空(含空字符串),填写内容时触发格式验证」,需调整Schema如下:
修正后的Schema配置
import z from "zod"; const formSchema = z.object({ phone: z.union([ z.string().min(10, "Type a complete number."), z.literal("") ]).optional(), email: z.union([ z.string().email({ message: "Type a valid email address." }), z.literal("") ]).optional(), website: z.union([ z.string().url('Please type a valid website (include http/https)'), z.literal("") ]).optional(), });
替代写法(更简洁)
如果不想用union,也可以用refine对非空值做验证:
const formSchema = z.object({ phone: z.string().optional().refine( val => !val || val.length >= 10, { message: "Type a complete number." } ), email: z.string().optional().refine( val => !val || z.string().email().safeParse(val).success, { message: "Type a valid email address." } ), website: z.string().optional().refine( val => !val || z.string().url().safeParse(val).success, { message: 'Please type a valid website (include http/https)' } ), });
补充说明
- 如果你的表单提交时会自动把空字符串转为
undefined(部分表单库的默认行为),那仅用.optional()即可,但多数场景下需要兼容空字符串的情况。 - 若需要支持
null值,可把z.literal("")换成z.union([z.literal(""), z.null()])。
内容的提问来源于stack exchange,提问作者ahols
相关产品推荐
相关产品推荐

