TypeScript报TS2345错误时出现的`0`类型是怎么来的?
问题原因
这个0类型来源于TypeScript对number类型的真值判定逻辑,你的推导漏了number类型本身自带假值字面量的规则:
- 你给
foo显式标注的类型是number | undefined,TypeScript不会因为你初始赋值为22就将类型收窄为真值数字,而是会保留number类型的全部可能取值:既包括非0的真值数字,也包括0、NaN这类假值数字。 - JavaScript中
&&运算符的规则是返回第一个遇到的假值操作数,全为真时返回最后一个操作数。对应到foo && new Date()的类型推导,TypeScript会把foo所有可能的假值类型都纳入表达式的返回范围:- 当
foo是假值undefined时,表达式返回undefined - 当
foo是假值0(属于number类型的合法取值)时,表达式返回0 - 当
foo是真值数字时,表达式返回new Date()也就是Date类型
- 当
- 最终整个表达式的推导类型是
0 | undefined | Date,其中undefined和Date都符合形参Date | undefined的要求,只有0(属于number类型)不匹配,所以TS抛出类型错误。报错信息里没有列出undefined,是因为它本身是合法的参数类型,不属于类型不兼容的部分。
修复方案
如果你期望的逻辑是「foo不是null/undefined时返回Date,否则返回undefined」,不要直接用&&做真值判断,改为明确判断空值即可:
// 仅当foo非null、非undefined时才执行new Date(),否则返回undefined bar(foo != null ? new Date() : undefined)
如果你的业务逻辑确实需要排除0、NaN等假值数字,才需要保留原有的真值判断逻辑,这时候可以显式做类型收窄匹配形参要求。
内容的提问来源于stack exchange,提问作者Sasgorilla
相关产品推荐
相关产品推荐

