网站搜索

typescript - 如何修复处理异步函数的泛型函数


我想创建一个通用函数,该函数接受一个异步函数,执行它,并在提供的函数遇到任何问题时捕获错误。

由于我有 JavaScript 背景,我能够创建以下函数来实现这一点。但我想使用泛型来改进它,却未能做到。

这段代码按预期工作。但我在 'msg' 参数上没有得到任何类型。

const botAsyncHandler = (fn:Function) => (msg: any) => {
  Promise.resolve(fn(msg)).catch(error => {
    console.log(error.message);
  });
};

所以我尝试写了以下内容

const botAsyncHandler = <T extends any>(fn:Function)=> (msg: T) => {
  Promise.resolve(fn(msg)).catch(error => {
    console.log(error.message);
    console.log('here');
  });
};

可悲的是,我的代码不能运行,并且 IDE 仍然在以下代码中隐式地告诉我 msg 的类型是 any

bot.on('photo', botAsyncHandler(async msg => {}))

( 返回:参数 'msg' 隐式具有 'any' 类型。)

但是突出显示 botAsyncHandler 显示如下内容:

botAsyncHandler<TelegramBot.Message>(fn: Function): (msg: TelegramBot.Message) => void

这似乎就是我想要的。我很好奇自己哪里出了错

答案#1

Function 类型毫无用处。不要使用它。fn 参数的类型类似于:(msg: T) => Promise<void>。或者你可以选择接受返回 void 的同步函数:(msg: T) => void | Promise<void>。

你可以写:

const botAsyncHandler = <T>(fn: (msg: T) => void | Promise<void>) => async (msg: T) => {
    try {
        await fn(msg);
    } catch (err) {
        console.log(err.message);
    }
};

const onString = (msg: string) => {};
const fn = botAsyncHandler(onString);
// Here, the type of 'fn' is: '(msg: string) => Promise<void>'

我无法测试,但你的代码应该可以按预期运行:

bot.on('photo', botAsyncHandler(async msg => {}))

答案#2

从你的示例用法来看:

bot.on('photo', botAsyncHandler(async msg => {}))

和 JavaScript 示例,看起来你正在尝试创建一个函数,该函数将返回另一个函数,当调用它时会调用原始函数,但会处理其中的错误。最简单的方法就是编写一个带有 try/catch 的 async 函数。JavaScript 版本:

const botAsyncHandler = (fn) => async (msg) => {
  try {
    await fn(msg);
  } catch (error) {
    console.log(error.message);
  }
};

为它添加带泛型的类型注解:

type AsyncHandler<T> = (arg: T) => {};
const botAsyncHandler = <T extends any>(fn: AsyncHandler<T>) => async (msg: T) => {
  try {
    await fn(msg);
  } catch (error) {
    console.log(error.message);
  }
};

那假设该函数必须声明一个形式参数。在游乐场上试试吧。

但是我不确定在这里添加类型参数是否对你有什么帮助,鉴于你使用的是 <T extends any>。