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

如何用Zod验证对象中仅存在指定属性之一?

Zod实现「必须且仅存在指定属性之一」的验证方案

直接给你可行的实现方式,同时解答关于Enum的疑问:

1. 核心方案:z.union + 单属性对象Schema

通过合并三个仅包含单个必填属性的对象Schema,就能实现「必须存在且仅存在三个属性之一」的验证逻辑:

import { z } from "zod";

// 替换z.any()为你实际需要的属性类型(比如z.string()、z.number()等)
const ResultsSchema = z.union([
  z.object({ resultType1: z.any() }),
  z.object({ resultType2: z.any() }),
  z.object({ resultType3: z.any() }),
]);

// 验证示例
ResultsSchema.parse({ resultType1: "success" }); // ✅ 通过
ResultsSchema.parse({ resultType2: 42 }); // ✅ 通过
ResultsSchema.parse({ resultType3: { data: [] } }); // ✅ 通过
ResultsSchema.parse({}); // ❌ 失败:无指定属性
ResultsSchema.parse({ resultType1: "foo", resultType2: "bar" }); // ❌ 失败:多属性共存

如果需要严格禁止对象包含额外属性,给每个对象Schema加上.strict()即可:

const StrictResultsSchema = z.union([
  z.object({ resultType1: z.any() }).strict(),
  z.object({ resultType2: z.any() }).strict(),
  z.object({ resultType3: z.any() }).strict(),
]);

StrictResultsSchema.parse({ resultType1: "foo", extraKey: "baz" }); // ❌ 失败:存在额外属性

2. 关于Enum的使用

Enum可以用来约束属性的取值范围,但无法直接实现「仅存在一个属性」的规则。不过你可以把Enum和上面的方案结合,同时实现属性存在规则和取值约束:

import { z } from "zod";

// 定义枚举
enum ResultEnum {
  TYPE1 = "RESULT_TYPE_1",
  TYPE2 = "RESULT_TYPE_2",
  TYPE3 = "RESULT_TYPE_3",
}

const ResultsWithEnumSchema = z.union([
  z.object({ resultType1: z.nativeEnum(ResultEnum) }),
  z.object({ resultType2: z.nativeEnum(ResultEnum) }),
  z.object({ resultType3: z.nativeEnum(ResultEnum) }),
]);

// 验证示例
ResultsWithEnumSchema.parse({ resultType1: ResultEnum.TYPE1 }); // ✅ 通过
ResultsWithEnumSchema.parse({ resultType2: "INVALID_VALUE" }); // ❌ 失败:取值不在枚举内

补充说明

你提到的required属性不适用这里——它只能确保某个属性必须存在,但无法阻止多个指定属性同时出现,所以达不到「仅存在一个」的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:51:02