Express+TypeScript路由报错:类型'(req: Request...)'无法赋值给'Application'
修复Express + TypeScript中asyncHandler导致的路由类型错误
错误信息
No overload matches this call. The last overload gave the following error. Argument of type '(req: Request, res: Response, next: NextFunction) => void' is not assignable to parameter of type 'Application<Record<string, any>>'.
问题根源
你的asyncHandler函数参数fn使用了any类型,导致TypeScript无法正确推断出包装后函数的类型,无法匹配Express路由方法(如post)要求的RequestHandler类型签名,从而抛出类型不兼容错误。
修复方案
给asyncHandler添加精确的TypeScript类型定义,明确它接收的是Express异步请求处理函数,并返回符合要求的处理函数:
- 修改
asyncHandler.ts的类型定义,替换any为Express的类型:
import { Request, Response, NextFunction, RequestHandler } from "express" // 定义异步处理函数的类型 type AsyncRequestHandler = (req: Request, res: Response, next: NextFunction) => Promise<void>; const asyncHandler = (fn: AsyncRequestHandler): RequestHandler => { return (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; }; export default asyncHandler;
如果需要支持更灵活的请求参数、响应体等类型,可以用泛型写法:
import { Request, Response, NextFunction, RequestHandler } from "express" const asyncHandler = <P = {}, ResBody = {}, ReqBody = {}, ReqQuery = {}>( fn: (req: Request<P, ResBody, ReqBody, ReqQuery>, res: Response<ResBody>, next: NextFunction) => Promise<void> ): RequestHandler<P, ResBody, ReqBody, ReqQuery> => { return (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; }; export default asyncHandler;
- (可选)优化控制器类型严谨性
给控制器的箭头函数添加返回类型,让类型推断更明确:
// controller.ts const signup = asyncHandler(async (req: Request, res: Response, next: NextFunction): Promise<void> => { res.status(200).json({ message: "signup" }); });
修复后的完整代码
asyncHandler.ts
import { Request, Response, NextFunction, RequestHandler } from "express" type AsyncRequestHandler = (req: Request, res: Response, next: NextFunction) => Promise<void>; const asyncHandler = (fn: AsyncRequestHandler): RequestHandler => { return (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; }; export default asyncHandler;
controller.ts
import { NextFunction, Request, Response } from "express"; import asyncHandler from "../utils/asyncHandler"; const signup = asyncHandler(async (req: Request, res: Response, next: NextFunction): Promise<void> => { res.status(200).json({ message: "signup" }); }); export { signup };
router.ts
import express from "express"; import { signup } from "../controller/controller"; const authRouter = express.Router(); authRouter.post("/signup", signup); export default authRouter;
原理说明
通过给asyncHandler明确类型约束,TypeScript可以准确推断出包装后的函数是Express路由所期望的RequestHandler类型,既解决了类型不匹配的错误,又保留了异步代码的错误捕获能力。
内容的提问来源于stack exchange,提问作者U. Watt
相关产品推荐
相关产品推荐

