如何让Zod允许未在Schema中定义的对象字段通过校验?
如何用Zod仅校验请求数据子集且保留未指定字段?
我尝试用Zod仅校验请求数据的一个子集,但它会过滤掉所有未明确指定的内容。代码示例如下:
const { z } = require('zod'); const schema = z.object({ params: z.object({ dependent_id: z.string() }), }) const req = { params: { dependent_id: "blah", bar: "baz" }, body: { foo: "bar" }, query: {} } const test = async () => { const { params, body, query } = await schema.parseAsync(req); console.log("params: ", params) console.log("body: ", body) console.log("query: ", query) } test()
当前输出:
params: { dependent_id: 'blah' } // 期望输出 { dependent_id: "blah", "bar": "baz" } body: undefined // 期望输出 { foo: "bar" } query: undefined // 期望输出 {}
我期望params保留dependent_id和bar字段,body和query也保留原有内容,该如何实现?
解决方法
Zod对象默认是严格模式,会自动移除未在schema中定义的键;同时如果根schema里没声明body和query字段,解析后这些字段会被直接丢弃。要实现需求,需要做两处调整:
- 允许params保留额外字段:给params的object schema添加
.passthrough()方法,Zod会校验指定字段的合法性,同时保留未定义的额外字段。 - 保留body和query字段:在根schema中明确声明
body和query字段,用z.any()匹配任意类型(如果不需要校验),确保这些字段被完整保留。
修改后的代码如下:
const { z } = require('zod'); const schema = z.object({ params: z.object({ dependent_id: z.string() }).passthrough(), // 开启passthrough保留params额外字段 body: z.any(), // 保留body字段,不做校验 query: z.any() // 保留query字段,不做校验 }) const req = { params: { dependent_id: "blah", bar: "baz" }, body: { foo: "bar" }, query: {} } const test = async () => { const { params, body, query } = await schema.parseAsync(req); console.log("params: ", params) console.log("body: ", body) console.log("query: ", query) } test()
此时输出会符合预期:
params: { dependent_id: 'blah', bar: 'baz' } body: { foo: 'bar' } query: {}
如果后续需要对body或query做部分校验,同样可以给它们的schema添加.passthrough(),比如:
body: z.object({ foo: z.string() }).passthrough() // 校验body中的foo字段,保留其他未定义字段
内容的提问来源于stack exchange,提问作者bigpotato
相关产品推荐
相关产品推荐

