TypeScript中catchAsync1报错“Property 'catch' does not exist on type 'void'”及catchAsync2、catchAsync3正确性咨询
问题分析与解决方案
嘿,我来帮你拆解这几个Express错误捕获函数的问题:
1. 为什么catchAsync1会报错?
你碰到的Property 'catch' does not exist on type 'void'错误,根源在于Express默认的RequestHandler类型返回值是void,不是Promise。你直接对handler(...args)调用.catch(),但这个调用没有返回Promise对象,自然没有catch方法可用。
要修复这个问题,我们需要明确约束传入的处理函数必须是返回Promise的异步函数,调整后的代码如下:
import { NextFunction, Request, Response } from 'express' // 自定义一个返回Promise的异步请求处理函数类型 type AsyncRequestHandler = (req: Request, res: Response, next: NextFunction) => Promise<void> export const catchAsync1 = (handler: AsyncRequestHandler) => (...args: [Request, Response, NextFunction]) => handler(...args).catch(args[2])
现在我们明确要求传入的handler必须返回Promise,这样.catch()调用就合法了。
2. catchAsync2和catchAsync3的写法是否正确?
从语法上来说,这两个函数在TypeScript里是合法的,但存在严重的逻辑缺陷:它们只能捕获同步抛出的错误,完全处理不了异步函数中抛出的错误。
举个例子说明问题
假设你有一个异步的请求处理函数:
const asyncHandler = async (req: Request, res: Response) => { await new Promise(resolve => setTimeout(resolve, 100)) throw new Error('这是一个异步错误') }
如果你用catchAsync2或catchAsync3包裹这个函数,里面的异步错误根本不会被try/catch捕获,也不会传给next(),最终会变成未处理的Promise拒绝。
如何修正?
要让这两个函数能处理异步错误,需要用async/await等待Promise完成,这样try/catch才能捕获异步抛出的错误:
// 修正后的catchAsync2 export const catchAsync2 = (handler: AsyncRequestHandler) => async (req: Request, res: Response, next: NextFunction) => { try { await handler(req, res, next) } catch (err) { next(err) } } // 修正后的catchAsync3 export const catchAsync3 = (handler: AsyncRequestHandler) => async (...args: [Request, Response, NextFunction]) => { try { await handler(...args) } catch (err) { args[2](err) } }
加上async关键字和await后,try/catch就能覆盖同步和异步两种错误场景了。
内容的提问来源于stack exchange,提问作者noiissyboy
相关产品推荐
相关产品推荐

