TypeScript中外部已断言变量为何在内部函数仍提示可能未定义?
为什么嵌套函数中的
cake仍提示“可能为undefined”? 先看问题中的代码:
function assert(condition: any): asserts condition { if (!condition) { throw new Error('assert failed'); } } class Cake { eat() {} } function maybeEatCake(cake?: Cake) { assert(typeof cake !== 'undefined'); function nested() { cake.eat(); // error: 'cake' is possibly 'undefined' } cake.eat(); }
原因解析
- TypeScript的类型收缩仅在当前函数的直接执行上下文生效,嵌套函数属于独立作用域,编译器不会将外部函数的类型收缩结果传递进去。
- 虽然外部函数通过
assert把cake的类型从Cake | undefined收缩成了Cake,但嵌套函数nested可能在外部函数断言执行后、cake被意外修改的时机调用(哪怕代码里没写修改逻辑,编译器也会考虑这种潜在可能性),因此它不认可外部的断言结果。
解决办法
办法1:将cake赋值给局部常量
常量的类型不会被改变,嵌套函数捕获这个常量后就能正确识别类型:
function maybeEatCake(cake?: Cake) { assert(typeof cake !== 'undefined'); const safeCake = cake; function nested() { safeCake.eat(); // 无报错 } cake.eat(); }
办法2:在嵌套函数内部再次断言
直接在嵌套函数里重新校验cake的类型:
function maybeEatCake(cake?: Cake) { assert(typeof cake !== 'undefined'); function nested() { assert(typeof cake !== 'undefined'); cake.eat(); // 无报错 } cake.eat(); }
内容的提问来源于stack exchange,提问作者rveerd
相关产品推荐
相关产品推荐

