typescript 异步函数类属如何使用泛型返回类型强制异步函数泛型?

dwbf0jvd  于 2022-12-24  发布在  TypeScript
关注(0)|答案(1)|浏览(168)

我试图创建一个函数,在拒绝之前重试异步函数多次。我想维护函数的类型脚本类型以重试,并需要弄清楚如何维护返回类型并强制传递的函数为PromiseLike
我们可以创建一个retry函数,它的类型化响应是从传递的函数中推断出来的,但是要确保传递的函数是PromiseLike并不容易,如果我们用如下的promise来 Package ReturnType<T>,那么我们将返回一个promise为T的promise,Promise<Promise<T>>而不是Promise<T>

export async function retry<T extends () => ReturnType<T>>(fn: T, retries: number = 1) {
  let attempts = 0;
  let response: ReturnType<T>;
  
  while (attempts < retries) {
    response = fn();
    try {
      console.log(`Evaluating attempt #${attempts} ...`);
      return await response;
    } catch (e) {
      console.log(`Attempt #${attempts} failed.`);
      if (attempts < retries) attempts = attempts + 1;
      else return response;
    }
  }
}

我试图解决的核心问题是如何强制通用约束是异步函数而不是任何Callable。使用TS实用程序(如PromisePromiseLike)是不可能的,因为返回类型将被一个promise Package 两次(在异步函数的情况下)。

gcuhipw9

gcuhipw91#

解决这个问题的方法是使用PromiseLike<Awaited<T>>,这个组合将强制传递的函数是异步的。当我们知道T将是一个承诺时,这个组合可以有效地被认为是PromiseLike约束。

export async function retry<T extends () => PromiseLike<Awaited<ReturnType<T>>>>(fn: T, retries: number = 1) {
  let attempts = 0;
  let response: PromiseLike<Awaited<ReturnType<T>>>;
  
  while (attempts < retries) {
    response = fn();
    try {
      console.log(`Evaluating attempt #${attempts} ...`);
      return await response;
    } catch (e) {
      console.log(`Attempt #${attempts} failed.`);
      if (attempts < retries) attempts = attempts + 1;
      else return response;
    }
  }

  throw Error("Invalid number of retries");
}

相关问题