如何修复处理异步功能的通用功能

时间:2019-04-07 15:58:18

标签: typescript generics types

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

由于我来自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的类型是隐式的

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

(返回:Parameter 'msg' implicitly has an 'any' type.

但突出显示botAsyncHandler会显示以下内容:

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

看起来像我想要的。我很好奇我要去哪里了

2 个答案:

答案 0 :(得分:1)

根据您的示例用法:

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

和JavaScript示例,似乎您正在尝试创建一个将返回一个函数的函数,该函数在调用时将调用原始函数,但会处理该函数中的错误。最简单的方法就是编写一个async / try的{​​{1}}函数。 JavaScript版本:

catch

向其中添加带有泛型的类型注释:

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

假定函数必须声明一个形式参数。 Live on the playground

但是我不确定在您使用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); } }; 的情况下添加类型参数可以在这里买任何东西。

答案 1 :(得分: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 => {}))