Express和Typescript - Error.stack和Error.status属性不存在

Joe*_*oel 21 javascript node.js express typescript

我正在尝试将现有的node.js项目从javascript转换为typescript.我一直在使用Visual Studio Express 4模板中的默认404错误捕获器:

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误消息: 类型'错误'上不存在属性'status'.

如果我尝试调用Error的.stack属性,我会收到类似的消息: 类型'Error'上不存在属性'stack'.

有谁知道这里发生了什么?

编辑: Steve Fenton指出我可以将错误状态放在响应对象上.但是,我的错误处理机制使用两个步骤:

  1. 创建404错误并设置其状态
  2. 将它交给以下通用处理程序:

    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: {}
        });
    });
    
    Run Code Online (Sandbox Code Playgroud)

因此,错误状态首先在Error对象上设置,然后由错误处理程序读回以决定如何处理错误.

bas*_*rat 14

您可以告诉TypeScript 您的用例Error可能包含status:

interface Error{
    status?: number;
}
Run Code Online (Sandbox Code Playgroud)

所以你得到:

interface Error{
    status?: number;
}

var err = new Error('Not Found');
err.status = 404;
Run Code Online (Sandbox Code Playgroud)

但是我不得不说你的快速代码是非惯用代码,但是如果你告诉它,TypeScript可以理解它.


Fen*_*ton 8

你把错误代码放在响应上......

app.use(function (req, res, next) {
    var err = new Error('Not Found');
    res.status(404)
    next(err);
});
Run Code Online (Sandbox Code Playgroud)


小智 8

如果我没记错的话,最好获得实际期望的类型。我找不到任何我正确的硬性支持,但我使用:

import createError, { HttpError } from 'http-errors';
Run Code Online (Sandbox Code Playgroud)

为了使所有类型完整,我还导入了使用的参数类型:

import express, { Request, Response, NextFunction } from 'express';
Run Code Online (Sandbox Code Playgroud)

我使用的实际函数如下所示:

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

在您的情况下,如果您想创建自己的错误:

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

或者更接近您的代码:

app.use((req: Request, res: Response, next: NextFunction) => {
  let err = new HttpError('Not found');
  err.status = 404;
  next(err);
});
Run Code Online (Sandbox Code Playgroud)


dmw*_*268 7

这通常是一个如何在 Typescript 中延迟初始化对象的问题。

执行此操作的理想方法是:

interface ErrorWithStatus extends Error {
    status: string
}

let foo = new Error() as ErrorWithStatus;
foo.status = '404';
Run Code Online (Sandbox Code Playgroud)

使用any, 或带有可为空字段的接口,会给您留下低于标准和弱合同。


Rei*_*ica 6

我认为最好的方法是不要通过将错误设置为any或创建新的Error类型来禁用类型检查,因为中已经存在一个类型@types/node

相反,您应该扩展该错误类型:

interface ResponseError extends Error {
  status?: number;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

import * as express from 'express';
interface Error {
  status?: number;
  message?: string;
}

app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用一些单词来帮助OP理解代码的哪一部分可以解决他们的问题,那么它会是一个更好的答案。 (2认同)