为何TypeScript中用变量存储类型判断结果无法实现类型收窄?
为什么将typeof判断结果存入变量后,TypeScript无法正确收窄unknown类型?
当把unknown类型的变量赋值给其他类型变量时,必须先做类型检查。但遇到一个疑问:把typeof first === 'number'的判断结果存入变量result,再用result作为if条件时,TypeScript会报错“Type 'unknown' is not assignable to type 'number'”;但直接在if条件里写typeof first === 'number'时却没有错误,这是为什么?
相关代码示例:
let first: unknown = 5; let second: number; const result = typeof first === 'number'; if(result){ second = first; // error : Type 'unknown' is not assignable to type 'number' } if(typeof first === 'number'){ second = first; // no errors }
原因解析
核心在于TypeScript的类型收窄逻辑只识别代码流中的直接类型守卫表达式,不支持通过间接变量关联类型判断:
- 直接在
if条件中写typeof first === 'number'时,TS的代码流分析会直接把这个表达式识别为针对first的类型守卫。它能明确知道:进入这个if分支的前提是first的类型为number,因此会自动把first的类型从unknown收窄为number,赋值自然合法。 - 当把判断结果存入
result变量后,TS无法建立result的布尔值与first类型之间的绑定关系。哪怕result是常量,TS也只会把它看作一个独立的布尔值,不会认为result为true就等价于first是number,因此不会对first进行类型收窄,赋值时就会触发类型不匹配的错误。
如果非要通过变量实现类似的类型收窄,可以使用自定义类型守卫函数,比如:
function isNumber(value: unknown): value is number { return typeof value === 'number'; } if(isNumber(first)){ second = first; // 无错误 }
内容的提问来源于stack exchange,提问作者Ahmed Sbai
相关产品推荐
相关产品推荐

