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

TypeScript:使用.call调用重试函数时如何推断返回类型?

如何让Function.prototype.call正确推断泛型函数的返回类型

问题原因

你的代码中response被推断为unknown,主要有两个核心原因:

  1. Parent类的token属性未明确标注类型,导致bar函数的返回类型推断不够清晰;
  2. 当通过Function.prototype.call调用带有自定义泛型的函数(如retryOnce)时,TypeScript的自动泛型推断可能因嵌套逻辑失效,无法识别fn的返回类型。

解决方案

1. 明确类属性类型,消除隐式any

先给Parent类的token加上类型标注,让TypeScript能准确推断bar的返回类型:

class Parent {
   token: number; // 明确标注属性类型
   constructor(token: number){
     this.token = token;
   }
   async someMethod(){
      const bar = () => someTypedFunction("variable", this.token);
      // ...
   }
}

2. 手动指定泛型参数

在调用retryOnce时,直接指定其泛型参数R,强制TypeScript识别返回类型:

async someMethod(){
  const bar = () => someTypedFunction("variable", this.token);
  const response = await retryOnce<Promise<string>>.call(this, bar);
  return response; // 此时response自动推断为string
}

3. 调整retryOnce的调用方式(更优雅)

如果不想依赖call的泛型推断逻辑,可以修改retryOnce的定义,将this作为显式参数传入,让类型推断更直接:

// 修改retryOnce,用ctx代替this隐式参数
async function retryOnce<R>(ctx: any, fn: () => R): Promise<R> {
   let isRetry = false;
   const execute = async () => {
      try{
         return await fn();
      }catch(error: any){
         if(!isRetry){
           isRetry = true;
           ctx.token = getNewToken();
           return execute();
         }else{
          throw Error();
         }
      }
  }
  return execute();
}

// 在Parent类中调用
async someMethod(){
  const bar = () => someTypedFunction("variable", this.token);
  const response = await retryOnce(this, bar);
  return response; // 自动推断为string
}

关于Function.prototype.call的泛型支持

Function.prototype.call本身是支持泛型的,其官方类型定义如下:

call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;

但当调用的函数自身带有泛型参数时,TypeScript的自动推断逻辑可能无法同时解析两层泛型关系,此时手动指定泛型参数或调整代码结构是更可靠的选择。

不要随意使用any绕过类型检查,这会丧失TypeScript的类型安全优势,优先通过明确类型标注或调整代码结构实现正确的类型推断。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:18:19