真实检查后访问可选道具的流程错误
flow error accessing optional prop after truthy check
流 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
是否已定义。
第一次访问 arg1.prop
属性 时流程很好,这是对 if
块内第一行的 arg1.prop.callable()
的调用。但是,流程会在后续尝试访问完全相同的 if
块中的 arg1.prop
属性时生成错误:
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();
}
};
这感觉不对。我做错了什么或遗漏了什么?
中查看
这在 FlowType 的 Type Refinement 部分中有记录:
Refinement Invalidations
It is also possible to invalidate refinements, for example:
// @flow
function otherMethod() { /* ... */ }
function method(value: { prop?: string }) {
if (value.prop) {
otherMethod();
// $ExpectError
value.prop.charAt(0);
}
}
The reason for this is that we don’t know that otherMethod() hasn’t
done something to our value.
...
There’s a straightforward way to get around this. Store the value
before calling another method and use the stored value instead. This
way you can prevent the refinement from invalidating.
// @flow
function otherMethod() { /* ... */ }
function method(value: { prop?: string }) {
if (value.prop) {
var prop = value.prop;
otherMethod();
prop.charAt(0);
}
}
因此,您最后一个案例中的解决方法似乎是避免此问题的建议方法。
流 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
是否已定义。
第一次访问 arg1.prop
属性 时流程很好,这是对 if
块内第一行的 arg1.prop.callable()
的调用。但是,流程会在后续尝试访问完全相同的 if
块中的 arg1.prop
属性时生成错误:
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();
}
};
这感觉不对。我做错了什么或遗漏了什么?
中查看这在 FlowType 的 Type Refinement 部分中有记录:
Refinement Invalidations
It is also possible to invalidate refinements, for example:
// @flow function otherMethod() { /* ... */ } function method(value: { prop?: string }) { if (value.prop) { otherMethod(); // $ExpectError value.prop.charAt(0); } }
The reason for this is that we don’t know that otherMethod() hasn’t done something to our value. ...
There’s a straightforward way to get around this. Store the value before calling another method and use the stored value instead. This way you can prevent the refinement from invalidating.
// @flow function otherMethod() { /* ... */ } function method(value: { prop?: string }) { if (value.prop) { var prop = value.prop; otherMethod(); prop.charAt(0); } }
因此,您最后一个案例中的解决方法似乎是避免此问题的建议方法。