如何使用Zod深度解析包含JSON字符串的Schema?
Zod是否支持直接解析嵌套JSON字符串的Schema?
你当前的实现方式是先验证请求结构,再手动解析JSON字符串并验证嵌套结构:
const z = require('zod') const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) }) const requestSchema = z.object({ payload: z.string() }) // ... const req = requestSchema.parse(request) const raw = JSON.parse(req.payload) const payload = payloadSchema.parse(raw) console.log(payload.name) // << this is what I'm interested into
你希望能通过类似z.string().json(payloadSchema)的写法,直接完成JSON字符串的解析和嵌套Schema验证,一步到位。
解决方案:使用Zod的transform方法实现链式解析验证
Zod本身没有内置的.json()方法,但可以通过transform转换实现你想要的效果,在验证请求结构的同时完成JSON解析和嵌套Schema验证:
const z = require('zod') const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) }) const requestSchema = z.object({ payload: z.string().transform((str, ctx) => { try { // 先解析JSON字符串 const parsedJson = JSON.parse(str) // 用payloadSchema验证解析后的对象 return payloadSchema.parse(parsedJson) } catch (err) { // 捕获JSON解析错误或Schema验证错误,添加自定义错误信息 ctx.addIssue({ code: z.ZodIssueCode.custom, message: "payload不是有效的JSON格式,或不符合数据要求" }) // 返回z.NEVER告知Zod验证失败 return z.NEVER } }) }) // 验证通过的示例 const validRequest = { payload: '{"name": "Alice", "age": 25}' } const req = requestSchema.parse(validRequest) console.log(req.payload.name) // 输出:Alice // 验证失败的示例(age不符合min(18)) const invalidRequest = { payload: '{"name": "Bob", "age": 17}' } requestSchema.parse(invalidRequest) // 抛出ZodError,提示age不符合要求
这样实现后,你只需要调用一次requestSchema.parse(request),就能直接得到已经解析并验证完成的req.payload对象,和你期望的写法效果完全一致。
内容的提问来源于stack exchange,提问作者Gerardo Lima
相关产品推荐
相关产品推荐

