Zod结合TypeORM参数校验时报safeParse is not a function错误
报错原因
payloadSchema.safeParse is not a function 错误的核心原因是:你定义的payloadSchema是一个包含body属性的普通JavaScript对象,并非Zod生成的Schema实例,普通对象本身不存在safeParse方法,调用时自然会抛出类型错误。
除此之外你的代码还存在两个连带问题:
- 外层普通对象不支持
z.infer做正确的类型推导 - Zod的
safeParse校验通过后,合法数据存储在返回值的data属性下,你直接从parsedData顶层取字段、冗余从req.body解构的写法,会导致后续赋值拿到undefined
修复步骤
- 调整Schema定义
你当前的校验目标是req.body,不需要在外层额外包一层带body字段的普通对象,直接将z.object()生成的Zod实例赋值给payloadSchema即可。 - 修正取值逻辑
校验通过后,所有字段从safeParse返回结果的data属性中获取,不要直接读取返回结果顶层、也不要从原始未校验的req.body中取值。
修复后完整代码
export const createProduct = async (req: Request, res: Response) => { try { // 直接定义请求体对应的Zod Schema,移除外层多余的普通对象包裹 const payloadSchema = z.object({ price: z.number({ required_error: "price is required", }), image: z.string({ required_error: "image is required", }), translations: z.object({ ge: z.object({ title: z.string({ required_error: "title is required", }), description: z.string({ required_error: "description is required", }), }), en: z.object({ title: z.string({ required_error: "title is required", }), description: z.string({ required_error: "description is required", }), }), }), }); type Payload = z.infer<typeof payloadSchema>; const parsedResult = payloadSchema.safeParse(req.body); if (!parsedResult.success) { res.status(400).send({ error: parsedResult.error, }); return; } // 从校验结果的data字段获取经过校验的合法数据 const { image, price, translations } = parsedResult.data; const product = new Product(); product.image = image; product.price = price; product.translations = translations; await product.save(); return res.json(product); } catch (e) { if (e instanceof Error) { return res.status(400).json({ message: e.message, }); } } };
补充提示
- 如果前端通过表单提交时
price字段传的是字符串类型,z.number()会校验失败,可以替换为z.coerce.number(),Zod会自动将传入的可转数字值转为数字类型后再做校验,减少不必要的类型报错。 - 如果你后续需要同时校验
req.params、req.query等其他请求字段,可以在外层拆分多个独立的Zod Schema分别校验对应字段,不要把Zod Schema嵌套在普通对象里再尝试对外层对象调用Zod方法。
内容的提问来源于stack exchange,提问作者BasDriver
相关产品推荐
相关产品推荐

