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

如何在Zod中让goals_other仅当goals含Other时必填?

解决Zod中条件必填字段的问题

你需要实现的是:当goals数组包含"Other"字符串时,强制要求填写goals_other字段。之前的refine逻辑有误,导致验证不生效,下面是具体的修正方案和原因说明。

原代码的问题

  1. 逻辑颠倒:你的refine函数在goals包含"Other"时返回true,这意味着Zod会判定验证通过,但实际上我们需要的是此时必须检查goals_other是否有有效内容,逻辑完全写反了。
  2. 字段定义错误:goals_other被定义为必填字符串,即使不选"Other",Zod也会强制要求该字段存在,不符合你的需求。

修正方案

方案一:修正refine逻辑(简洁版)

先将goals_other设为可选,再调整refine的验证条件:

const zodSchema = z
  .object({
    goals: z.array(z.string()).nonempty("At least one goal is required"),
    goals_other: z.string().optional(), // 先标记为可选字段
  })
  .refine(
    (data) => {
      // 当goals包含"Other"时,必须确保goals_other非空(去除首尾空格后)
      if (data.goals.includes("Other")) {
        return data.goals_other?.trim() !== "";
      }
      // 不包含"Other"时,直接通过验证
      return true;
    },
    {
      message: "Required, please specify other goals",
      path: ["goals_other"], // 指定错误提示的字段路径
    }
  );

方案二:使用superRefine(精细控制版)

如果需要更灵活的错误处理,比如自定义错误代码,可以用superRefine:

const zodSchema = z
  .object({
    goals: z.array(z.string()).nonempty("At least one goal is required"),
    goals_other: z.string().optional(),
  })
  .superRefine((data, ctx) => {
    // 当包含"Other"且goals_other为空/未填写时,手动添加错误
    if (data.goals.includes("Other") && (!data.goals_other || data.goals_other.trim() === "")) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: "Required, please specify other goals",
        path: ["goals_other"],
      });
    }
  });

方案三:用Union区分两种场景(结构清晰版)

如果希望Schema的逻辑结构更直观,可以用z.union拆分两种情况:

const zodSchema = z.union([
  // 场景1:goals不含"Other",goals_other可选
  z.object({
    goals: z.array(z.string()).nonempty().refine(goals => !goals.includes("Other")),
    goals_other: z.string().optional(),
  }),
  // 场景2:goals含"Other",goals_other必填
  z.object({
    goals: z.array(z.string()).nonempty().refine(goals => goals.includes("Other")),
    goals_other: z.string().nonempty("Required, please specify other goals"),
  }),
]);

注意事项

  • 必须将goals_other初始设为optional(),否则Zod会默认要求该字段始终存在。
  • 加入trim()检查可以避免用户输入纯空格被误判为有效内容。

内容的提问来源于stack exchange,提问作者psych0groov3

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:19