【问题标题】:In TypeScript infer generic types of callback from argument在 TypeScript 中从参数推断通用类型的回调
【发布时间】:2021-11-08 06:57:23
【问题描述】:

有一堆SO问题符合这个标题描述,但据我所知,他们都没有回答这个问题。

我正在尝试围绕 express RequestHandler 编写一个包装器,该包装器会捕获异步处理程序中的错误并使用该错误调用 next

这个想法是我可以做这样的事情:

function tryCatchNext<
  P = ParamsDictionary,
  ResBody = any,
  ReqBody = any,
  ReqQuery = ParsedQs,
  Locals extends Record<string, any> = Record<string, any>
>(
  callback: RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>
): RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {
  return async (req, res, next) => {
    try {
      await callback(req, res, next);
    } catch (err) {
      next(err);
    }
  };
}

app.get('/:foo', tryCatchNext(async (req, res, next) => {
  // `foo` is not a known parameter, but no error
  if (req.params.foo === 'bar') {
    throw new Error('That was a bar.');
  }

  // does not result in an error
  // @ts-expect-error
  console.log(req.params.bar);

  res.send('Not a bar');
}));

如果我只有处理程序,req 知道它的params。在tryCatchNext() req 内没有。我怀疑这是因为它试图从传递给它的回调中推断返回值,而不是其上下文的泛型类型。

如果我在它前面加上一个无操作处理程序,它就可以完美地工作,这样.get()...handlers 休息参数就已经被推断出来了。

app
  .get('/:foo', (req, res, next) => next(), tryCatchNext(async (req, res, next) => {
    // ...
  }));

有没有办法在不明确指定每个泛型类型参数的情况下解决这个问题?

【问题讨论】:

  • 请分享带有突出显示错误的可重现示例
  • 正在处理它,但没有错误,因为默认的req.params 只是一个Record&lt;string, string&gt;
  • 好的,只要在你有问题的那一行评论一下
  • 我知道你的痛苦))
  • 您是否尝试过超载app.get

标签: typescript


【解决方案1】:

由于这是专门为 express RequestHandler 完成的包装,您可能只想使用 Parameters 实用程序类型 (doc) 来获取作为 app.get 函数的第二个参数接受的回调类型,这样:

type CallbackType = Parameters<typeof app.get>[1];

function tryCatchNext( callback: CallbackType ): CallbackType {
  return async (req, res, next) => {
    try {
      await callback(req, res, next);
    } catch (err) {
      next(err);
    }
  };
}

我想深入研究类型定义可能会发现更好的类型 (doc),但我认为这应该可行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-09
    • 2019-12-06
    • 2022-01-07
    • 2020-03-11
    • 2020-10-31
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多