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

升级TypeScript至3.7.4后出现TS2339编译错误求助

解决TypeScript 3.7.4中Promise.all返回类型推断的编译错误

我刚帮你捋清楚这个问题——从TS 3.4.1升级到3.7.4后,Promise.all的类型推断逻辑发生了变化,这才导致了这个编译错误。先复盘下你的场景:

你的配置与代码

tsconfig.json:

{ 
  "compilerOptions": { 
    "baseUrl": ".", 
    "outDir": "dist", 
    "module": "commonjs", 
    "target": "es6", 
    "experimentalDecorators": true, 
    "emitDecoratorMetadata": true, 
    "sourceMap": true 
  } 
}

可复现代码:

async function f1(): Promise<{a: number}> { 
  return Promise.resolve({} as any); 
}
async function f2(): Promise<{a: number, b: number}> { 
  return Promise.resolve({} as any); 
}
(async ()=> { 
  const tp = await Promise.all([f1(), f2()]); 
  let a = tp[0].a; 
  let b = tp[1].a; 
  let c = tp[1].b; // 这里报错:Property 'b' does not exist on type '{ a: number; }'
  console.log(a, b, c); 
})();

问题原因

在TS 3.4.1中,Promise.all([f1(), f2()])会被推断为Promise<[{a: number}, {a: number, b: number}]>(元组类型),所以tp[1]的类型明确是{a: number, b: number},访问b不会有问题。

但TS 3.7.4对数组字面量的类型推断做了调整:当你传递普通数组给Promise.all时,它会默认把数组推断为联合类型的数组,也就是Promise<({a: number} | {a: number, b: number})[]>。这时候tp[1]的类型是{a: number} | {a: number, b: number},TS无法确定它一定包含b属性,所以抛出了编译错误。

解决方案

这里有几种简单的修复方式,选你觉得最顺手的就行:

方案1:用as const断言数组为元组

给Promise.all的参数加上as const,强制TS把数组推断为元组类型,这样返回值的类型就会保留每个Promise的具体返回类型:

const tp = await Promise.all([f1(), f2()] as const);

方案2:显式指定Promise.all的泛型参数

直接告诉TSPromise.all的返回元组类型,明确每个位置的类型:

const tp = await Promise.all<[{a: number}, {a: number, b: number}]>([f1(), f2()]);

方案3:给tp变量显式指定类型

如果不想修改Promise.all的调用,也可以直接给tp变量声明元组类型:

const tp: [{a: number}, {a: number, b: number}] = await Promise.all([f1(), f2()]);

这三种方法都能让TS正确识别tp[1]的类型,解决Property 'b' does not exist的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:37:41