You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:12:12