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

Express and Typescript - Error.stack and Error.status properties do not exist

本文关键字:属性 不存在 status stack Typescript-Error Express Error      更新时间:2023-09-26

我正在尝试将现有的node.js项目从javascript转换为typescript。我一直在使用VisualStudioExpress4模板中的默认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);
});

但是,我收到以下错误消息:类型"Error"上不存在属性"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: {}
        });
    });
    

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

扩展全局Error

您可以告诉TypeScript,对于,您的用例Error上可能有一个status

interface Error {
    status?: number;
}

所以你得到了:

interface Error {
    status?: number;
}
var err = new Error('Not Found');
err.status = 404;

备选方案

将状态置于res上并发送err。例如:

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    res.status(404); // using response here
    next(err);
});

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

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

interface ResponseError extends Error {
  status?: number;
}
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
  });
});

您将错误代码放在响应上。。。

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

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

理想的方法是:

interface ErrorWithStatus extends Error {
    status: string
}
let foo = new Error() as ErrorWithStatus;
foo.status = '404';

使用any或具有可为null字段的接口,会留下子协定和弱协定。

如果我没有错的话,最好得到实际期望的类型。我找不到任何我是对的硬支持,但我使用:

import createError, { HttpError } from 'http-errors';

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

import express, { Request, Response, NextFunction } from 'express';

我使用的实际功能如下:

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

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

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

或更接近您的代码:

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

TypeScript中的另一个选项:

let err: any;
err = new Error();
err.status = 404;

我刚选了

var err = new Error('Not Found');
err['status'] = 404;