我的目标是定义一个自定义的 Express 端点包装器,因此它相应地包装异步函数和处理程序错误(将来它可能会做更多的事情)。
处理程序非常基本,我已经这样定义了它。它按我的预期工作:
import type {Request, RequestHandler, Response} from 'express';
type Handler = (
fn: (req: Request, res: Response) => Promise<void> | void
) => RequestHandler;
const handler: Handler = fn => async (req, res, next) => {
try {
await fn(req, res);
} catch (e) {
next(e);
}
};
现在,我发现 Express 中的路由器方法是接受类型参数的通用函数,可用于定义响应对象的形状,如下所示。这也按预期工作:
import express from 'express';
const app = express();
app.get<{}, {data: number}>(
'/posts',
(_req, res) => {
// @ts-expect-error Argument of type '{ hello: string; }' is not assignable to parameter of type '{ data: number; }'.
res.send({hello: 'world'});
}),
);
但是,当我用自定义处理程序包装端点处理程序时,它不起作用;编译器不会提示。我不明白如何/为什么。我尝试过更改 Handler 类型的定义,但仍然不起作用。有人知道我如何让它发挥作用吗?
完整代码如下:
import express from 'express';
import type {Request, RequestHandler, Response} from 'express';
type Handler = (
fn: (req: Request, res: Response) => Promise<void> | void
) => RequestHandler;
const handler: Handler = fn => async (req, res, next) => {
try {
await fn(req, res);
} catch (e) {
next(e);
}
};
const app = express();
app.get<{}, {data: number}>(
'/posts',
handler((_req, res) => {
// @ts-expect-error Argument of type '{ should_not: string; }' is not assignable to parameter of type '{ data: number; }'.
res.send({should_not: 'compile'});
})
);
app.listen(4000, () => console.log('Listening on port 4000...'));
我已经多次尝试打乱和声明处理程序类型定义,但没有任何效果。编译器根本不会提示。
最佳答案
通过包装处理程序,您还可以覆盖类型,并且 ResBody
的类型更改为 any
(当您不指定响应类型时。<使用 em>default 类型,即 any)。这就是类型检查无法正常工作的原因,并且 ts-expect-error
显示未使用的“@ts-expect-error”指令
。
要解决此问题,您还需要考虑自定义处理程序中的 ResBody
,并告诉 Express 使用定义的自定义类型而不是 any
。
type Handler = <T>(
fn: (req: Request, res: Response<T>) => Promise<void> | void
) => RequestHandler;
interface ResBody {
data: number
}
app.get<{}, ResBody>(
'/posts',
handler<ResBody>((_req, res) => {
// @ts-expect-error Argument of type '{ should_not: string; }' is not assignable to parameter of type '{ data: number; }'.
res.send({should_not: 'compile'});
})
);
关于node.js - 如何输入自定义异步 Express 处理程序,以便透明地传递通用类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75171104/