Flowtype不断要求空检查

Blu*_*lub 11 flowtype

我想知道如何避免这些无效的空检查或至少理解这一点是什么,因为它似乎适得其反.

如果我省略null检查,Flowtype给我一个错误:

var myEl = new MyElement()
if (document.body != null) { // error on next line if omitted
    document.body.appendChild(myEl)
}
Run Code Online (Sandbox Code Playgroud)

我必须在每个回调中对文档正文执行null检查,因为谁知道,也许正文在这里是空的?!我认为这是完全矫枉过正的.不仅如此,还有这么简单的零检查有什么意义呢?它只是默默地跳过程序的一个重要部分,并在其他地方展示未定义的行为,并使调试应用程序更加困难.如果在这里发生错误,我真的更喜欢只有一个null异常,因为要确定我在javascript中编写的这个小的2行代码段必须在flowtype中是这样的:

var myEl = new MyElement()
if (document.body != null) {
    document.body.appendChild(myEl)
} else {
    console.error("null error")
}
Run Code Online (Sandbox Code Playgroud)

所以4个额外的代码行和一些嵌套只是为了追踪我免费得到的东西,如果我只是让应用程序遇到错误.我在每个querySelector上都需要这4行.在每一个文件上.在每个getElementByTagName上.仅这一点可能会使我的整个代码库增加10%.如此严格地执行这一点有什么意义?

在其他语言中,我也可以根据需要逐渐尝试捕捉这些热点,流程也不允许我这样做.无论我是否添加try-catch,它都会显示错误.

log*_*yth 9

通过使用类型检查器,您将选择执行它的规则.访问可空类型的属性是这些限制之一.因此,如果您想要为null值设置异常,则需要显式抛出以向Flow证明它是您想要的.例如,您可以制作一个类似的模块

if (!document.body) throw new Error("Unexpectedly missing <body>.");
export const body: HTMLElement = document.body;

export function querySelector(el: HTMLElement, selector: string): HTMLElement {
    const result = el.querySelector(selector);
    if (!result) throw new Error(`Failed to match: ${selector}`);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

通过抛出,这些函数在所有情况下都明确地说"我将返回一个元素",在这种null情况下,它们会抛出异常.

然后在您的普通代码中,保证您可以使用它们

import {body, querySelector} from "./utils";

body.appendChild(document.createElement('div'));

querySelector(body, 'div').setAttribute('thing', 'value');
Run Code Online (Sandbox Code Playgroud)

并且它将检查财产.

  • 另外值得注意的是Flow特殊情况下的`invariant`名称.你可以`从'assert'`导入invariant或者为`invariant'提供一个实现,然后你就可以编写`invariant(document.body)`而不是你想出的`if` /`throw`行.键入更快,IMO读得更好. (2认同)