【发布时间】:2019-02-25 15:33:10
【问题描述】:
正如https://strongloop.github.io/strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/#using-es7-asyncawait 所展示的,我想为我的所有异步 Express 处理程序使用一个包装器来捕获那里发生的任何错误,但在 TypeScript 的类型化版本中。
我想出了这个:(wrap.ts)
import { NextFunction, RequestHandler, Response, Request } from 'express';
type AsyncRequestHandler = (req: Request, res: Response, next: NextFunction) => Promise<any>;
/**
* Catches errors and passes them to the next callback
* @param handler Async express request handler/middleware potentially throwing errors
* @returns Async express request handler with error handling
*/
export default (handler: AsyncRequestHandler): RequestHandler => {
return (req, res, next) => {
return handler(req, res, next).catch(next);
};
};
我想构建一个带有一些端点的 REST API,例如 PUT /users/:userId 和 DELETE /users/:userId。为方便起见,我不想在每个处理程序的数据库中查询 ID 为 userId 的特定用户,而是使用中间件将其存储在 req 中。这意味着我必须使用修改后的Request 接口来添加user 属性的处理程序定义,例如UserRequest.
import express, { Request } from 'express';
import wrap from './wrap';
const app = express();
app.use('/users/:userId', wrap(async (req, res, next) => {
// set req.user ...
}));
export interface UserRequest extends Request {
user: User;
}
app.put('/users/:userId', wrap(async (req: UserRequest, res) => {
// do something with req.user ...
}));
// ...
这在不使用wrap 时是可能的,但对于wrap 的这种类型定义则不行。 TypeScript 编译器产生以下错误:
Argument of type '(req: UserRequest, res: Response) => Promise<void>' is not assignable to parameter of type 'AsyncRequestHandler'.
Types of parameters 'req' and 'req' are incompatible.
Type 'Request' is not assignable to type 'UserRequest'.
Property 'user' is missing in type 'Request'.
完成此任务的“TypeScript 方式”是什么?
【问题讨论】:
-
我猜你必须使
wrap泛型而不是Request类型 -
谢谢。你能提示一下这是如何工作的吗?
-
这样你就可以使用
wrap<UserRequest>(async (req, res) => { … req.user … -
我可以重现错误的唯一方法是打开
strictFunctionTypes,然后即使我不调用wrap,我也会在app.put的参数上收到错误。如果我将wrap设为通用,那么当包装的处理程序传递给app.put时,我不会得到wrap的参数错误,而是得到它。如果您使用strictFunctionTypes,则必须在某些时候协调UserRequest和Request之间的差异。例如,您可以使用一个单独的包装函数,该函数将采用UserRequest的处理程序转换为采用Request的处理程序。
标签: node.js typescript express asynchronous promise