TypeScript Express 错误函数

Old*_*zer 13 express typescript typescript-typings

在Typescript中编码时错误处理函数的四个参数的类型是什么?

app.use((err: ??, req: ??, res: ??, next: ??) => { });
Run Code Online (Sandbox Code Playgroud)

我正在使用 VS Code,没有提供任何提示。我在所有四个参数下都得到红色的摆动线。

错误显示“参数隐式具有‘任何’类型”。其实我对这个消息感到困惑。如果它把它当作一种any类型,那么这不是一个有效的选择吗?

Tom*_*ech 20

该函数本身具有以下签名(取自绝对类型):

export type ErrorRequestHandler = (err: any, req: Request, res: Response, next: NextFunction) => any;
Run Code Online (Sandbox Code Playgroud)

因此,您可以将函数声明为类型变量,也可以ErrorRequestHandler根据该定义键入参数。

注意:“express-serve-static-core”的类型是通过“express”的类型导入和重新导出的,这是我寻找上述定义的地方。

import type { ErrorRequestHandler } from "express";
Run Code Online (Sandbox Code Playgroud)
const errorHandler: ErrorRequestHandler = (err, req, res, next) => {};

app.use(errorHandler);
Run Code Online (Sandbox Code Playgroud)

关于您的第二个问题与 hidden 相关any,它是导致问题的“隐式”部分,如果您显式键入 asany则不会有任何错误(但也不会有任何类型;考虑unknown改用)。

您也可以noImplicitAny在编译器配置中禁用,但我个人不推荐它,因为它可以保护您免受几类错误的影响。


Yog*_*ity 7

自定义错误类型

Usingany完全放弃了 Typescript 的类型检查优势。因为在 JavaScript 中,throw任何东西都可以,对于err参数,类型unknown可以从 Typescript 3.0 开始使用:

app.use((err: unknown, req: Request, res: Response, next: NextFunction) => { })
Run Code Online (Sandbox Code Playgroud)

例子

如果需要,创建自定义错误,如下所示:

// HttpException.ts in exceptions directory of your project.

export class HttpException extends Error {
  public status: number
  public message: string
  constructor(status: number, message: string) {
    super(message)
    this.status = status
    this.message = message
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在您使用它的任何地方导入自定义错误:

import { HttpException } from './exceptions/HttpException'

app.use((req: Request, res: Response, next: NextFunction) => {
    const err = new HttpException(404, 'Not Found')
    // Do something with error here...
    next(err)
})

app.use((err: unknown, req: Request, res: Response, next: NextFunction) => {
    if (err instanceof HttpException) {
        // Do something more with the error here...
    }
    next(err)
})
Run Code Online (Sandbox Code Playgroud)

由于类型errunknown,我们不能直接访问或修改err。首先,我们需要检查使用instanceof它的类型,因此智能将 转换err为该类型(HttpException在我们的例子中)。

我们可以HttpException在需要时向类添加任何属性和方法,就像我们添加了status和 一样message


类型定义

如果你还没有这样做,你需要为你的 Typescript 项目安装 Node.js 和 Express.js 的类型定义。这将确保 types RequestResponse并且NextFunction将被识别和自动导入。

要为 Node.js 安装类型定义:

npm install --save-dev @types/node
Run Code Online (Sandbox Code Playgroud)

要为 Express.js 安装类型定义:

npm install --save-dev @types/express
Run Code Online (Sandbox Code Playgroud)

就是这样!希望有帮助。


小智 6

我不知道为什么 Typescript 没有得到我们正在传递一个错误处理程序。

这些是我发现可能的解决方案:

app.use((err, req, res, next) => {}) // KO    

const inVariable : ErrorRequestHandler = (err, req, res, next) => {};

app.use(inVariable); // ok
app.use(((err, req, res, next) => {}) as ErrorRequestHandler); // ok
Run Code Online (Sandbox Code Playgroud)

  • 将处理程序显式转换为“ErrorRequestHandler”的方法对我来说很有效。 (2认同)