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

TypeScript无法正确推断扩展类型,如何优化NextApiRequest类型定义?

解决NextApiRequest body的TypeScript类型推断问题

问题核心

你需要让NextApiRequest的body属性具备明确的TypeScript类型,同时要求自定义请求类型必须包含method字段,可选包含body和query。当前req.body被推断为any而非预期的{lol: string},根源在于基础类型的泛型约束和类型提取逻辑有误。

解决方案

通过重新定义类型约束和泛型关联逻辑,让TS能正确推断body和query的类型:

1. 定义符合要求的请求类型约束

先明确SageApiRequest的结构:必须包含method,body和query为可选字段,同时支持泛型传入具体类型:

import type { NextApiRequest, NextApiResponse } from 'next';

// 约束SageApiRequest必须包含method,body和query可选且支持自定义类型
type SageApiRequest<Method extends string, Body = unknown, Query = unknown> = {
  method: Method;
  body?: Body;
  query?: Query;
};

2. 改造BaseSageRequest,关联泛型类型

调整BaseSageRequest,让它从传入的SageApiRequest类型中提取body和query的具体类型,覆盖NextApiRequest默认的any类型:

// 从传入的SageApiRequest类型中提取body和query,覆盖NextApiRequest的对应字段
type BaseSageRequest<T extends SageApiRequest<string>> = NextApiRequest & {
  // 直接使用T中定义的body类型,支持可选场景
  body: T['body'];
  // 同理处理query
  query: T['query'];
};

如果需要强制某些接口的body为必填,可以修改为:

type BaseSageRequest<T extends SageApiRequest<string>> = NextApiRequest & {
  body: T['body'] extends undefined ? never : T['body'];
  query: T['query'] extends undefined ? never : T['query'];
};

3. 在接口函数中使用正确的类型

定义具体接口的请求类型,然后传入BaseSageRequest:

// 定义创建聊天接口的请求类型:POST方法,body为{lol: string}
type CreateChatRequest = SageApiRequest<'POST', { lol: string }>;

function createChat(req: BaseSageRequest<CreateChatRequest>, res: NextApiResponse) {
  // 此时req.body的类型为{lol: string},TS会提供类型提示和校验
  const message = req.body.lol;
  // ... 业务逻辑处理
}

原理说明

  • 通过SageApiRequest的泛型约束,确保所有自定义请求类型都必须包含method,同时支持灵活定义body和query的类型。
  • BaseSageRequest通过交叉类型将NextApiRequest与提取自SageApiRequest的body/query类型合并,覆盖了原NextApiRequest中body为any的默认类型,让TS能正确推断具体类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:42:11