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

如何使用Zod discriminatedUnion结合枚举鉴别器,无需列出所有枚举值?

解决Zod基于枚举鉴别字段的条件验证问题

针对你遇到的场景——当枚举字段为VAL1时otherField必填字符串,为其他枚举值时otherField必须为undefined,无需逐个枚举所有值的解决方案如下:

方法一:使用z.union配合refine过滤枚举值

这种方式保留分支式结构,同时避免手动列出所有枚举值:

import { z } from "zod";
import { MyEnum } from "@prisma/client"; // 导入Prisma生成的枚举

const schema = z.union([
  // 分支1:鉴别字段为VAL1时,otherField必填字符串
  z.object({
    discriminatorField: z.literal(MyEnum.VAL1),
    otherField: z.string()
  }),
  // 分支2:鉴别字段为枚举中除VAL1外的其他值,otherField必须为undefined
  z.object({
    discriminatorField: z.nativeEnum(MyEnum).refine(val => val !== MyEnum.VAL1),
    otherField: z.undefined()
  })
]);

为什么可行?

z.nativeEnum(MyEnum).refine(...)会过滤掉VAL1,确保两个分支的鉴别值完全互斥,解决了直接用nativeEnum导致的重叠报错问题。Zod会按顺序匹配分支,优先校验第一个分支,符合条件则直接通过,否则进入第二个分支。

方法二:使用单对象加refine全局校验

如果觉得分支结构冗余,可以直接在单个对象Schema后添加refine做条件校验:

import { z } from "zod";
import { MyEnum } from "@prisma/client";

const schema = z.object({
  discriminatorField: z.nativeEnum(MyEnum),
  otherField: z.string().optional()
}).refine(data => {
  // 核心条件判断
  return data.discriminatorField === MyEnum.VAL1 
    ? typeof data.otherField === "string" 
    : data.otherField === undefined;
}, {
  // 自定义错误提示
  message: "鉴别字段为VAL1时otherField必须是字符串,其他情况必须为undefined"
});

这种方式更简洁,适合逻辑不复杂的场景,错误提示也可根据需求自定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:43:14