真空检查后访问可选道具的流量错误

时间:2018-06-01 17:28:58

标签: javascript flowtype

流量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属性时,流程很好,这是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 repl here on flow.org

中查看此内容

1 个答案:

答案 0 :(得分:1)

这在FlowType' Type Refinement部分中有记录:

  

细化失效

     

也可以使细化无效,例如:

// @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);
  }
}

因此,最终案例中的解决方法似乎是避免此问题的建议方法。