javascript - 真实检查后访问可选道具的流程错误
问题描述
流 0.67.1(但行为在 0.73.1 中继续存在)
例子:
type PropOptional = {
prop?: ComplexType
};
type ComplexType = {
callable: () => void,
anotherCallable: () => void
};
function usePropOptional(arg1: PropOptional) {
if (arg1.prop) {
arg1.prop.callable();
arg1.prop.anotherCallable();
arg1.prop.callable();
}
};
arg1.prop
该函数在访问 上的任何属性之前检查是否存在arg1.prop
。这应该足以验证arg1.prop
已定义。
Flow 在第一次arg1.prop
访问属性时很好,这是对块arg1.prop.callable()
内第一行的调用。if
但是,流在随后尝试访问arg1.prop
完全相同的if
块中的属性时会产生错误:
arg1.prop.anotherCallable();
arg1.prop.callable();
我被迫在每一行前面加上一个死记硬背的arg1.prop &&
真实性检查,或者重新分配arg1.prop
给 if 块内的一个局部变量:
function usePropOptional(arg1: PropOptional) {
if (arg1.prop) {
const reallyExists = arg1.prop;
reallyExists.callable();
reallyExists.anotherCallable();
reallyExists.callable();
}
};
这感觉不对。我做错了什么或错过了什么?
您可以在 flow.org 上的 flow repl中检查这一点。
解决方案
这记录在 FlowType 的类型优化部分:
细化失效
也可以使细化无效,例如:
// @flow function otherMethod() { /* ... */ } function method(value: { prop?: string }) { if (value.prop) { otherMethod(); // $ExpectError value.prop.charAt(0); } }
这样做的原因是我们不知道 otherMethod() 没有对我们的价值做任何事情。...
有一种简单的方法可以解决这个问题。在调用另一个方法之前存储该值并改用存储的值。这样,您可以防止细化失效。
// @flow function otherMethod() { /* ... */ } function method(value: { prop?: string }) { if (value.prop) { var prop = value.prop; otherMethod(); prop.charAt(0); } }
因此,在您的最终情况下,解决方法似乎是避免此问题的建议方法。
推荐阅读
- google-apps-script - 如果网站已在另一个浏览器选项卡中打开,则使用 Google 应用脚本防止用户在表格中打开 url 链接
- javascript - 如何根据值过滤对象数组
- python - 内核在地理 tiff 图像上死于 rasterio.open().read()
- prolog - 如何编写序言程序以在给定范围之间打印?
- winforms - C++/CLI Winform - 是否可以有多个文本框的 1 个事件处理程序
- java - 我的 Flutter 应用程序无法在我的 android 模拟器 (Andriod Studio) 上启动
- java - Android 异步任务未按预期工作
- google-sheets - 搜索日期格式的单元格时有没有办法使用 SUMIF?谷歌表格
- azure - 如何阻止 Excel 在 azure datafactory 管道中将数字更改为零?
- ethereum - MetaMask 会支持 EIP-1559 吗?