如何修改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
相关产品推荐
相关产品推荐

