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

如何为TypeScript自定义throttlePromise函数正确添加类型标注?

为节流异步函数完善TypeScript类型标注

你的throttlePromise函数实现了特殊的节流逻辑——忽略中间调用,仅在间隔结束时执行最后一次被阻止的调用。下面是优化后的类型标注版本,彻底减少了any的使用,同时保证类型安全:

export function throttlePromise<T, This = unknown, Args extends any[] = any[]>(
  fn: (this: This, ...args: Args) => Promise<T>,
  ms: number
) {
  let queuedFnCall = false;
  let queuedFnCallThis: This | null = null;
  let queuedFnCallArgs: Args = [] as Args;
  let runningPromise: Promise<T> | null = null;

  function invokeFn(fnThis: This, fnArgs: Args): Promise<T> {
    if (runningPromise === null) {
      runningPromise = new Promise<T>((resolve, reject) => {
        const fnPromise = fn.apply(fnThis, fnArgs);

        Promise.allSettled([wait(ms), fnPromise]).then((results) => {
          runningPromise = null;

          if (queuedFnCall) {
            queuedFnCall = false;
            invokeFn(queuedFnCallThis!, queuedFnCallArgs)
              .then(resolve)
              .catch(reject);
          } else if (results[1].status === 'fulfilled') {
            resolve(results[1].value);
          } else {
            reject(results[1].reason);
          }
        });
      });
    } else {
      queuedFnCall = true;
      queuedFnCallThis = fnThis;
      queuedFnCallArgs = fnArgs;
    }

    return runningPromise;
  }

  return function (this: This, ...args: Args): Promise<T> {
    return invokeFn(this, args);
  };
}

function wait(ms: number) {
  return new Promise<void>((resolve) => setTimeout(resolve, ms));
}

关键类型优化说明:

  • 新增泛型参数This和Args:分别约束原异步函数的this上下文和参数列表,彻底替代模糊的any类型
  • 明确队列变量类型:queuedFnCallThis标注为This | null,queuedFnCallArgs标注为Args,确保队列中存储的调用信息类型准确
  • 修正runningPromise类型:从Promise<any> | null改为Promise<T> | null,与原函数的返回值类型保持一致
  • 返回函数严格约束:包装后的函数继承原函数的this和参数类型,调用时会自动进行类型校验,避免参数不匹配的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:31:16