Express 和 Typescript - Error.stack 和 Error.status 属性不存在
Posted
技术标签:
【中文标题】Express 和 Typescript - Error.stack 和 Error.status 属性不存在【英文标题】:Express and Typescript - Error.stack and Error.status properties do not exist 【发布时间】:2015-05-01 19:40:08 【问题描述】:我正在尝试将现有的 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);
);
但是,我收到以下错误消息: 类型“错误”上不存在属性“状态”。
如果我尝试调用错误的 .stack 属性,我会收到类似的消息: “错误”类型上不存在属性“堆栈”。
有人知道这里发生了什么吗?
编辑: Steve Fenton 指出我可以将错误状态放在响应对象上。但是,我的错误处理机制使用了两步过程:
-
创建 404 错误并设置其状态
将其交给以下通用处理程序:
app.use(function (err, req, res, next)
res.status(err.status || 500);
res.render('error',
message: err.message,
error:
);
);
所以首先在Error对象上设置错误状态,然后由错误处理程序回读以决定如何处理错误。
【问题讨论】:
【参考方案1】:扩展全球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);
);
【讨论】:
谢谢巴萨拉特。我只是假设这是一种适当的做事方式,因为它是在 Visual Studio Express 4 模板中完成的。 哎哟。 糟糕的视觉工作室团队 这个模板,是js模板还是typescript模板? OP 的代码在 Express 方面看起来很惯用(每个 [expressjs.com/en/guide/error-handling.html],即res.statusCode
设置自 err.status
(或 err.statusCode
)。(也headers
) - 但是 Express 类型不应该包含类似:declare global // Shouldn't Express do this? interface Error status?: number; statusCode?: number; headers: [string]
的内容吗?(抱歉格式不好) - 是否已经在某个地方讨论过这个问题?
你如何告诉 typescript Error
上面有 status
?【参考方案2】:
在我看来,最好的方法不是通过将错误设置为any
来禁用类型检查,或者创建一个新的Error
类型,因为@types/node
中已经存在一个类型。
相反,您应该扩展该错误类型:
interface ResponseError extends Error
status?: number;
【讨论】:
我会推荐上面的方法,它对我来说看起来更复杂 有什么方法可以让我在全球范围内做到这一点? 我认为接受的答案可以满足您的需要【参考方案3】:您将错误代码放在响应中...
app.use(function (req, res, next)
var err = new Error('Not Found');
res.status(404)
next(err);
);
【讨论】:
【参考方案4】: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
);
);
【讨论】:
如果你用一些词来帮助 OP 理解你的代码的哪一部分解决了他们的问题,它会得到一个更好的答案。【参考方案5】:这一般是关于如何在 Typescript 中懒惰地初始化对象的问题。
理想的方法是:
interface ErrorWithStatus extends Error
status: string
let foo = new Error() as ErrorWithStatus;
foo.status = '404';
使用any
,或带有可为空字段的接口,会让你的合约低于标准和弱。
【讨论】:
应该是as ErrorWithStatus
。但你得到了我的支持:-)【参考方案6】:
如果我没记错的话,最好总是得到实际预期的类型。我找不到任何正确的支持,但我使用:
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);
);
【讨论】:
【参考方案7】:TypeScript 中的另一个选项:
let err: any;
err = new Error();
err.status = 404;
【讨论】:
创建类型any
完全放弃了Typescript 的最大优势之一——类型检查和执行。这个解决方案可能首先违背了 OP 从 JavaScript 切换到 Typescript 的目标。我认为其他一些更好【参考方案8】:
TypeScript 中的另一个选项:
const err: status?: number, message:string = new Error('Not Found');
err.status = 404;
【讨论】:
我认为扩展 Error 是一个更好的解决方案,因为它允许 TypeScript 编译器理解实例化对象的完整形状。此解决方案将理解仅限于状态和消息属性。【参考方案9】:我刚去
var err = new Error('Not Found');
err['status'] = 404;
【讨论】:
OP 正在使用 TypeScript。此解决方案将放弃使用智能感知/自动完成 b/c 的能力,编译器将无法理解错误的完整形式,因此我认为其他一些更好。以上是关于Express 和 Typescript - Error.stack 和 Error.status 属性不存在的主要内容,如果未能解决你的问题,请参考以下文章
Express 和 Typescript - Error.stack 和 Error.status 属性不存在
Typescript 2.2 Express req, res 隐含任何
如何将 Typescript、NodeJS 和 Express 应用程序部署到 Heroku
如何在 Typescript 项目中使用 express-mysql-session?