问题描述
在共享代码 (Playground Link) 中,编译器抛出错误 Object is possibly 'null'.
是否有可能调用 refresh
以便 viewer
可以为 null,前提是在 viewer
函数中 topLayer
为 null 时提前返回?
如果不是,在嵌套函数的情况下,打字稿没有缩小范围的原因是什么?
解决方法
这里有点接近,但显然不是同一个精心设计的例子:
declare var viewer: { key: string } | null;
let _viewer = { key: 'key' } as { key: string } | null
Object.defineProperty(window,'viewer',{
get() {
const val = _viewer;
_viewer = null;
return val
}
})
function topLayer() {
if (!viewer) return;
function refresh() {
console.log(viewer.key); // shows `Cannot read property 'key' of null` error
}
refresh();
}
topLayer();
尽管实际上 typescript 使用了一些启发式来缩小类型,但显然不会使用 viewer
变量的所有可能值运行您的程序。新函数 refresh
为 viewer
自由(不是局部变量也不是参数)变量创建新的作用域,但它仍未缩小范围。
如果你改写为:
function topLayer() {
if (!viewer) return;
function refresh(viewer: { key: string }) {
console.log(viewer.key);
}
refresh(viewer);
}
一切都按预期进行。