node.js - 如何输入自定义异步 Express 处理程序,以便透明地传递通用类型参数

标签 node.js typescript express typescript-generics type-parameter

我的目标是定义一个自定义的 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/

相关文章:

node.js - nodejs加密解密有什么问题?

node.js - 是否可以在 mongoosejs 模式中填充自引用?

typescript - 如何做一个条件泛型类型,它在未定义时有值,但在未定义和另一件事时没有值

javascript - 通过触发对话框覆盖的函数在 Angular 组件之间传递值

node.js - NodeJS/express : Cache and 304 status code

node.js - NodeJS : How to stop a web server?

node.js - 网络套接字 : cannot detect client connection on internet disconnect

javascript - 单击 Angular 9 中页面的其他位置时隐藏通知

node.js - 如何从 Vue.js 组件连接到 socket.io?

javascript - 如何从Node发送自定义错误消息,并使用catch显示它?