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

使用Zod的parse方法时,合法属性为何被移除?

Zod使用.or()时parse移除合法属性的原因与解决办法

问题场景

使用Zod的schema.parse验证输入时,发现合法属性被移除,问题出在.or()方法的使用上,示例代码如下:

const z = require('zod')

const baseSchema = z.object({})

const extendedSchema = baseSchema.extend({
  a: z.string()
})

const optionsSchema = baseSchema.or(extendedSchema)

const options = {
  a: 'A'
}

console.log('before `schema.parse`', JSON.stringify(options))      // 输出: before `schema.parse` {"a":"A"}
const validOptions = optionsSchema.parse(options)
console.log('-after `schema.parse`', JSON.stringify(validOptions)) // 输出: -after `schema.parse` {}

原因解析

这不是Zod的Bug,而是.or()(本质是Union类型)的工作机制导致的:

  • Zod会按你传入的顺序依次尝试匹配Union中的每个Schema,一旦某个Schema匹配成功,就会立即用该Schema来解析输入并返回结果,不会再尝试后续的Schema。
  • 示例中baseSchema是一个空对象Schema,它能匹配任何对象(空对象Schema默认允许额外属性),但解析时会严格按照Schema的结构输出——也就是空对象。所以输入{a: 'A'}时,首先匹配上了baseSchema,直接输出空对象,完全不会走到extendedSchema的匹配逻辑。

解决办法

调整.or()中Schema的顺序,把更具体、约束更强的Schema放在前面,让Zod优先匹配更精准的规则:

// 调换顺序,先匹配带a属性的extendedSchema
const optionsSchema = extendedSchema.or(baseSchema)

const validOptions = optionsSchema.parse(options)
console.log('-after `schema.parse`', JSON.stringify(validOptions)) // 输出: -after `schema.parse` {"a":"A"}

这样输入{a: 'A'}时,会先匹配到extendedSchema,解析后自然保留a属性;如果输入的是空对象,则会匹配到baseSchema,输出空对象,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:23:17