You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中结合展开运算符与Parameters工具类型并修复类型错误

修复TypeScript缓存高阶函数的参数迭代器错误

我写了一个能缓存异步函数结果的高阶函数,传入相同参数时会返回缓存的Promise。但去掉//@ts-ignore注释后,TypeScript报错:Type 'Parameters<FN>' must have a '[Symbol.iterator]()' method that returns an iterator. ts(2488)。

原函数代码:

function memoize<FN extends (...args: any) => Promise<any>>(fn: FN) {
  const cache: Record<string, Promise<Awaited<ReturnType<FN>>>> = {};

  return (...args: Parameters<FN>) => {
    const cacheKey = JSON.stringify(args);

    if (!(cacheKey in cache)) {
      // @ts-ignore
      const promise = fn(...args);
      cache[cacheKey] = promise;
    }

    return cache[cacheKey];
  };
}

使用示例:

const cachedFunction = memoize(async (id: string) => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`))
const resultFromAPI = cachedFunction("1")
const resultFromCache = cachedFunction("1")

问题根源

原来的泛型约束FN extends (...args: any) => Promise<any>太宽泛,args: any允许函数参数是任意类型,TypeScript没法确定Parameters<FN>对应的参数列表是可迭代的元组,所以对fn(...args)的展开操作报错。

修复方法

只需要把泛型约束里的(...args: any)改成(...args: any[]),明确限定被包装的函数接收的是数组/元组类型的参数列表,这样TypeScript就能确定Parameters<FN>是可迭代的,展开操作就合法了。

修复后的代码:

function memoize<FN extends (...args: any[]) => Promise<any>>(fn: FN) {
  const cache: Record<string, Promise<Awaited<ReturnType<FN>>>> = {};

  return (...args: Parameters<FN>) => {
    const cacheKey = JSON.stringify(args);

    if (!(cacheKey in cache)) {
      const promise = fn(...args);
      cache[cacheKey] = promise;
    }

    return cache[cacheKey];
  };
}

补充说明

这个修改只是明确了参数类型的约束,不会影响函数的实际功能——原来的使用示例依然可以正常运行,同时TypeScript的类型检查也能通过,不需要再用//@ts-ignore来规避错误。

内容的提问来源于stack exchange,提问作者jansepke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:00:22