TypeScript报错:传入的Promise无调用签名,无法调用
问题原因及解决方案
核心问题
你给retry方法的promise参数定义的类型是Promise<any>,这表示它是一个Promise实例,但你在代码里却把它当成函数调用(promise())——Promise实例本身不具备调用能力,TypeScript因此提示“没有调用签名”。
实际场景中,重试逻辑需要每次重新执行异步操作,所以应该让调用者传入一个返回Promise的函数,而非直接传入Promise实例(否则第一次Promise完成后,重试时只会重复拿到已完成的结果,失去重试意义)。
修复步骤
- 修改
promise参数的类型为() => Promise<any>,明确这是一个无参数、返回Promise的函数; - (可选)把宽泛的
Function类型替换为更明确的() => void来定义onRetry,提升类型安全性。
修正后的完整代码
export class ExponentialBackoffUtils { public static retry(promiseFn: () => Promise<any>, maxRetries: number, onRetry?: () => void) { function waitFor(milliseconds: number) { return new Promise((resolve) => setTimeout(resolve, milliseconds)); } async function retryWithBackoff(retries: number) { try { if (retries > 0) { const timeToWait = 2 ** retries * 1000; await waitFor(timeToWait); } console.log('Retries: ', retries); // 移除测试用的强制抛出逻辑,实际使用时直接执行传入的异步函数 // if (retries < 3) { // throw new Error(); // } return await promiseFn(); } catch (e) { if (retries < maxRetries) { onRetry?.(); // 用可选链简化条件判断 return retryWithBackoff(retries + 1); } else { throw e; } } } return retryWithBackoff(0); } }
额外说明
- 将参数名改为
promiseFn更直观,能清晰区分“返回Promise的函数”和“Promise实例”; - 原代码中
if (retries < 3) throw new Error()是测试重试逻辑的临时代码,实际使用时记得移除,否则会强制触发3次重试才执行真实异步操作。
内容的提问来源于stack exchange,提问作者Jo Momma
相关产品推荐
相关产品推荐

