为什么Flow仍然抱怨document.getElementById的空值

问题描述 投票:1回答:2

为什么即使使用IF检查,Flow仍然会抱怨可能为null的值

if(document && document.getElementById("myID") && document.getElementById("myID").offsetWidth){
 console.log(document.getElementById("myID").offsetWidth);
}

给出了这个错误

   ^ property `offsetWidth`. Property cannot be accessed on possibly null value
flowtype
2个回答
6
投票

Flow无法知道第一次调用getElementById的成功意味着后者也会成功。据他所知,阅读offsetWidth属性可能会导致getElementById在下次调用时开始返回null

您需要存储该值,例如

const myIdEl = document && document.getElementById("myID");

if(myIdEl && myIdEl.offsetWidth) {
   console.log(myIdEl.offsetWidth);
}

这样,myIdEl在被引用后就无法变为null。


0
投票

对于FlowType中的HTMLElement(以及像VideoHTMLElement这样的HTMLElement的扩展),我建议使用instanceof来验证Type并验证它不是null。

另外,我不认为你需要检查document是否存在,这是在flow(1)*中全局定义的

<HTMLElement>示例

const myIdEl: ?HTMLElement = document.getElementById('myID'); 
if (myIdEl instanceof HTMLElement) {
    // continue 
    console.log(myIdEl.offsetWidth);
}

<HTMLSelectElement>示例

const selectEl: ?HTMLElement = document.getElementById('someSelectElement');

// Checks correct type (!null !undefined come for free)
if (selectEl instanceof HTMLSelectElement) {
   const selectedVal = selectEl.options[selectEl.selectedIndex].value; 
}

<HTMLVideoElement>使用不变量的示例

import invariant from 'invariant';

const videoContent = document.getElementById('video-player');
invariant(videoContent instanceof HTMLVideoElement, 'No video element');

// do stuff with video api 
videoContent.volume = 0;
videoContent.plause();

  1. https://github.com/facebook/flow/blob/f3f29f7fd8c5aa73ac5a8a546ccfbc29cd7505fe/lib/dom.js#L1288
© www.soinside.com 2019 - 2024. All rights reserved.