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

如何在Next.js中为NextApiRequest的body设置强类型以获得类型安全

Next.js 12 API路由请求Body类型安全实现方案

第一步:扩展支持泛型的NextApiRequest类型

Next.js 12 原生提供的NextApiRequest默认不支持泛型传入,我们可以通过接口继承的方式自定义扩展类型,支持传入query、body的泛型定义:

import type { NextApiRequest } from 'next';

// TQuery为请求query参数类型,TBody为请求body类型
export interface NextApiRequestExtend<TQuery = {}, TBody = any> extends NextApiRequest {
  query: TQuery;
  body: TBody;
}

第二步:添加运行时参数校验

TypeScript的类型校验仅在编译阶段生效,要实现真正的类型安全,必须添加运行时的参数格式校验,你可以通过自定义类型守卫实现:

import { NextApiResponse } from "next";
import type { NextApiRequestExtend } from './你存放扩展类型的文件路径';

// 定义Body的类型
interface IBody {
  test: string;
  value: number;
}

// 类型守卫函数,运行时校验入参是否符合IBody格式
function isIBody(body: unknown): body is IBody {
  return (
    typeof body === 'object' &&
    body !== null &&
    typeof (body as IBody).test === 'string' &&
    typeof (body as IBody).value === 'number'
  );
}

const handler = async (
  req: NextApiRequestExtend<{}, IBody>, // 直接指定body的类型为IBody
  res: NextApiResponse
): Promise<void> => {
  // 先校验请求方法
  if (req.method !== 'POST') {
    return res.status(405).json({ error: '仅支持POST请求' });
  }

  // 运行时校验body格式
  if (!isIBody(req.body)) {
    return res.status(400).json({ error: '请求参数格式错误' });
  }

  // 此处req.body会被TypeScript自动推断为IBody类型,无需as强制转换,完全类型安全
  const { test, value } = req.body;
  console.log(test, value);

  res.status(200).json({ text: "Hello" });
};

export default handler;

可选简化方案:使用Schema校验库

如果你的接口参数较多,手写类型守卫效率较低,可以使用zod、yup这类Schema校验库简化实现,以zod为例:

import { z } from 'zod';

// 定义Body的Schema
const BodySchema = z.object({
  test: z.string(),
  value: z.number()
});

// 在handler中校验
try {
  const body = BodySchema.parse(req.body);
  // 此处body自动获得类型,无需额外定义interface
} catch (e) {
  return res.status(400).json({ error: '参数格式错误' });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:36:04