如何让Zod在对象而非其属性上返回表单验证错误?
解决方案
1. 修改Zod验证Schema,将错误绑定到user字段
通过Zod的refine方法,对user对象整体做验证,并指定错误路径为user,替代原来在user.id上的必填错误:
const formValidationSchema = z.object({ // 保留你的其他字段 user: z.object({ id: z.number(), name: z.string(), type: z.object({ id: z.number() // 注意:此处和你的Form类型中type.id为string存在不一致,建议统一类型 }, { required_error: "Choose type of user" }) }).refine( (user) => typeof user.id === "number" && !isNaN(user.id), { message: "Choose a user", path: ["user"], // 强制错误绑定到user字段 } ), });
如果需要处理user为null/undefined等更复杂场景,可使用superRefine:
const formValidationSchema = z.object({ // 保留你的其他字段 user: z.object({ id: z.number(), name: z.string(), type: z.object({ id: z.number() }, { required_error: "Choose type of user" }) }).superRefine((user, ctx) => { if (!user.id || isNaN(user.id)) { ctx.addIssue({ code: z.ZodIssueCode.invalid_type, expected: "number", received: user.id === undefined ? "undefined" : typeof user.id, message: "Choose a user", path: [] // 当前层级为user,path[]对应最终路径"user" }); } }), });
2. 调整表单组件的错误绑定
将UserSelect的error属性从form.errors["user.id"]改为form.errors["user"]:
<UserSelect value={form.user} onChange={(value) => form.setFieldValue("user", value)} error={form.errors["user"]} />
3. 统一类型定义(可选但建议)
你的Form类型中user.type.id为string,但Zod验证定义为number,类型不匹配会导致潜在问题,建议统一:
type Form = { // 保留你的其他字段 user: { id: number; name: string; type: { id: number; // 和Zod验证规则统一 } } }
修改完成后,提交空表单时错误格式会符合你的预期:
{ "user": "Choose a user", "user.type": "Choose type of user" }
同时选择用户后,user字段验证通过,错误提示会自动消失。
内容的提问来源于stack exchange,提问作者mTv
相关产品推荐
相关产品推荐

