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

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
修复步骤
  1. 调整Schema定义
    你当前的校验目标是req.body,不需要在外层额外包一层带body字段的普通对象,直接将z.object()生成的Zod实例赋值给payloadSchema即可。
  2. 修正取值逻辑
    校验通过后,所有字段从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:18:27