【问题标题】:TypeScript Express Error FunctionTypeScript Express 错误函数
【发布时间】:2018-10-17 12:51:26
【问题描述】:

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

app.use((err: ??, req: ??, res: ??, next: ??) => { });

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

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

【问题讨论】:

    标签: typescript express typescript-typings


    【解决方案1】:

    自定义错误类型

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

    app.use((err: unknown, req: Request, res: Response, next: NextFunction) => { })
    

    示例

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

    // 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
      }
    }
    

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

    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)
    })
    

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

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


    类型定义

    如果您还没有完成,您需要为您的 Typescript 项目安装 Node.js 和 Express.js 的类型定义。这将确保类型 RequestResponseNextFunction 将被识别并自动导入。

    为 Node.js 安装类型定义:

    npm install --save-dev @types/node
    

    为 Express.js 安装类型定义:

    npm install --save-dev @types/express
    

    就是这样!希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      函数本身具有以下签名(取自DefinitelyTyped):

      export type ErrorRequestHandler = (err: any, req: Request, res: Response, next: NextFunction) => any;
      

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

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

      import type { ErrorRequestHandler } from "express";
      
      const errorHandler: ErrorRequestHandler = (err, req, res, next) => {};
      
      app.use(errorHandler);
      

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

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

      【讨论】:

      • 谢谢。当我将函数显式声明为 ErrorRequestHandler 类型时,它会说“声明类型既不是 'void' 也不是 'any' 的函数必须返回一个值。”我可以为这个功能返回什么?我试过 return res.render(... 但那是 void 类型。
      • @OldGeezer 听起来你可能把输入放错了地方,可能是函数(...): ErrorRequestHandler => ... 的返回类型。键入函数的一种方法是使用const yourHandler: ErrorRequestHandler = (...) => ...,然后使用app.use(yourHandler)
      【解决方案3】:

      我不知道为什么 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
      

      【讨论】:

      • 将处理程序显式转换为ErrorRequestHandler 的方法对我有用。
      猜你喜欢
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2019-11-03
      • 1970-01-01
      相关资源
      最近更新 更多