找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1007

积分

0

好友

145

主题
发表于 前天 02:24 | 查看: 8| 回复: 0

我们面临一个挑战:下面的 retry 函数无法正确推断其返回的 Promise 类型。你能修复它吗?

async function retry(
  fn: () => Promise<any>,
  retries: number = 5
): Promise<any> {
  try {
    return await fn();
  } catch (err) {
    if (retries > 0) {
      console.log("Retrying...");
      return await retry(fn, retries - 1);
    }
    throw err;
  }
}

const getString = () => Promise.resolve("hello");
const getNumber = () => Promise.resolve(42);

retry(getString).then((str) => {
  // str 应该是 string 类型,而不是 any!
  console.log(str);
});

retry(getNumber).then((num) => {
  // num 应该是 number 类型,而不是 any!
  console.log(num);
});

问题根源分析

上述问题的根源在于,我们在 retry 函数中为 Promise 的返回值类型使用了 any

async function retry(
  fn: () => Promise<any>,
  retries: number = 5
): Promise<any> {
  // ...
}

这导致当我们调用 retry 函数时,TypeScript 无法推断出解析后 Promise 的确切类型,它被笼统地标记为 any

这带来了显著的问题:any 类型会使其作用域内的所有类型检查失效。这意味着,仅仅因为使用了 retry 这个可复用函数,我们就可能丢失传递给它的函数原本具有的类型安全保障。这是使用 TypeScript 进行开发时一个常见痛点——开发者有时会为了方便而使用 any,但这会牺牲掉类型系统带来的核心优势。

解决方案:引入泛型类型参数

为了使函数既灵活又类型安全,我们可以使用泛型来替代固定的 any 类型。

async function retry<T>(
  fn: () => Promise<T>,
  retries: number = 5
): Promise<T> {
  try {
    return await fn();
  } catch (err) {
    if (retries > 0) {
      console.log("Retrying...");
      return await retry(fn, retries - 1);
    }
    throw err;
  }
}

我们为 retry 函数添加了一个泛型类型参数 T。这个 T 随后被用于两个方面:

  1. 约束 fn 参数,表示它必须返回一个 Promise<T>
  2. 作为 retry 函数自身的返回类型 Promise<T>

通过这样的改造,retry 函数就变成了一个泛型函数。它能够从传入的运行时函数中捕获并传递其返回的 Promise 的具体类型信息。

const getString = () => Promise.resolve("hello");
retry(getString).then((str) => {
  // str 现在是明确的 string 类型!
  console.log(str);
});

现在,TypeScript 能够根据 getString 的返回值类型,正确地推断出调用 retry(getString) 后返回的 Promise 解析值为 string 类型,而不再是模糊的 any。泛型参数的名字可以是任何你喜欢的,常见的命名如 TDataTResponse,前缀 T 通常用来表示这是一个类型参数。通过这种方式,我们极大地提升了函数的通用性和使用时的类型安全性,这是构建高质量、可维护的 JavaScriptTypeScript 应用的关键一步。




上一篇:Spring Cloud Gateway微服务网关实战与面试核心解析
下一篇:SGLang调度器源码深度解析:连续批处理与GPU资源优化
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 16:31 , Processed in 0.140545 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表