TypeScript使用箭头函数时为何无法通过控制流和never类型收窄?
为什么TypeScript里箭头函数版的
fail没法触发类型收窄,但函数声明版的fail2可以?这是bug吗? 这不是TypeScript的bug,是类型系统设计逻辑导致的差异。
TypeScript对函数声明和const声明的箭头函数,类型处理逻辑不一样:
- 函数声明
fail2会被直接识别为返回never类型的函数,当在data === null的分支里调用它时,TS能明确判断这个分支会直接终止(因为never代表函数永远不会正常返回),所以会把后续的data类型收窄成string。 - 而用const声明的箭头函数
fail,TS默认会给它推断出(message?: string) => never这个类型,但这个类型没有被标记为「不可变」。TS的控制流分析对这类函数调用,不会像函数声明那样直接认定分支终止,自然没法完成类型收窄。
要让箭头函数也能触发类型收窄,有两种办法:
- 用
as const锁定函数类型:
const fail = ((message?: string): never => { throw new Error(message); }) as const;
- 直接给变量指定精确的函数类型:
const fail: (message?: string) => never = (message?) => { throw new Error(message); };
改完之后调用fail(),TS就能像处理fail2()一样完成类型收窄,return data就不会报错了。
内容的提问来源于stack exchange,提问作者Zachiah
相关产品推荐
相关产品推荐

