You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TypeScript三元表达式下Promise类型不兼容问题及原因咨询

问题原因解析

这是个挺典型的TypeScript类型推断细节问题,我来一步步拆解为什么会出现这个编译错误:

1. 单独分支的类型推断

先看两个单独赋值的情况:

  • Promise.resolve():TypeScript 2.7会推断它的返回类型是Promise<void>——因为你没有传入任何resolve的值,内部默认resolve的是undefined,对应void类型。
  • new Promise(() => {}):由于你在executor函数里没有调用resolvereject,TS会推断这个Promise的泛型参数为{},也就是它的类型是Promise<{}>

2. 三元表达式的类型合并问题

当你用三元表达式true ? Promise.resolve() : new Promise(() => {})赋值时,TS会把两个分支的类型合并为联合类型Promise<void> | Promise<{}>

而TypeScript对联合类型的方法调用有个严格规则:调用联合类型的方法时,传入的参数必须能同时满足联合类型中每一个成员的方法签名。

具体到then方法:

  • Promise<void>.thenonfulfilled回调期望的是(value: void) => ...类型的函数
  • Promise<{}>.thenonfulfilled回调期望的是(value: {}) => ...类型的函数

你传入的() => {}是一个无参函数,它无法匹配Promise<{}>.then的回调要求(后者需要接受一个{}类型的参数,哪怕你不用这个参数)。因此,整个联合类型的then方法找不到兼容的调用签名,就抛出了编译错误。

3. 显式指定类型为什么能解决问题

当你把变量类型显式指定为Promise<void | {}>时,本质是把它变成了单个Promise类型,其泛型参数是联合类型,而不是两个Promise类型的联合。

这时候then方法的onfulfilled回调只需要接受void | {}类型的参数,你的无参回调() => {}完全符合要求(TS允许回调忽略参数,只要参数类型是兼容的),所以编译就能正常通过了。

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

火山引擎 最新活动