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

如何修改Zod Schema实现对象仅允许指定属性二选一?

Zod Schema 限制对象仅含指定二选一属性

我需要定义一个包含必填name属性的对象,要求该对象只能包含nickname或other属性中的一个。目前的Schema写法如下,但当同时传入nickname和other时校验依然通过,不符合需求:

export const studentSchema = z
  .object({
    name: z.string().min(1).max(20)
  })
  .and(
    z
      .object({
        nickname: z.string().min(1).max(20)
      })
      .or(
        z.object({
          other: z.string().min(1).max(14)
        })
      )
  )

错误输入示例(此时校验不应通过但实际通过):

{
  "name": "John",
  "nickname": "any",
  "other": "play"
}

解决方案

方法一:使用.strict()约束多余属性

给每个分支的对象Schema添加.strict(),同时顶层也加上.strict(),Zod会直接拒绝未声明的属性,从而避免同时出现两个目标属性:

export const studentSchema = z
  .object({
    name: z.string().min(1).max(20)
  })
  .and(
    z
      .object({
        nickname: z.string().min(1).max(20)
      })
      .strict() // 禁止该分支出现未声明属性
      .or(
        z.object({
          other: z.string().min(1).max(14)
        }).strict() // 禁止该分支出现未声明属性
      )
  )
  .strict(); // 顶层禁止未声明属性

方法二:使用.refine()自定义校验逻辑

如果需要更灵活的校验逻辑,可以先将两个属性设为可选,再通过.refine()确保恰好有一个属性存在:

export const studentSchema = z
  .object({
    name: z.string().min(1).max(20),
    nickname: z.string().min(1).max(20).optional(),
    other: z.string().min(1).max(14).optional()
  })
  .refine(
    (data) => {
      const hasNickname = data.nickname !== undefined;
      const hasOther = data.other !== undefined;
      // 确保两者恰好有一个存在
      return hasNickname !== hasOther;
    },
    {
      message: "必须且只能提供nickname或other中的一个属性",
      path: ["nickname/other"]
    }
  );

合法输入示例

{
  "name": "John",
  "nickname": "any"
}

或

{
  "name": "John",
  "other": "play"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:11:06