访问时的流错误可能是在真理检查后定义的函数表达式中输入的

时间:2018-06-14 16:33:58

标签: javascript flowtype

流量0.74.0

该代码可在flow基于网络的REPL here

上找到

Flow在theMethod函数内的以下语句中标记错误:another(() => theArg.thing)

  

无法获取theArg.thing,因为null或undefined

中缺少属性thing

代码:

type MyType = {
  thing: string
};

function aFunc(action: MyType){ console.log('in aFunc', action.thing);} ;

function another(callback: () => string) { console.log('in another', callback());};

function theMethod(theArg: ?MyType) {
  if (!theArg) return;

  aFunc(theArg);

  // flow doesn't complain about this
  console.log('in theMethod', theArg.thing);

  // flow doesn't like accessing theArg.thing in this arrow function
  another(() => theArg.thing);
}

虽然theArg可能被输入,theMethod只有在通过真理检查后才会访问theArg

使优化失效?

由于某些方法调用在真值检查后可能会影响theArg,因此错误似乎不是流invalidating type refinement的结果。

Flow并没有抱怨theArg.thing可能为null / undefined,它抱怨在真实检查后theArg可能为null / undefined。虽然外部函数可以改变theArg引用的对象,但它不能更改对象theArg引用的对象。

我通过在调用单独的函数(theArg)后直接访问theMethod函数体console.log('in theMethod', theArg.thing);中的aFunc来仔细检查此期望。流程还可以。

起重?

当我在theArg中的函数表达式中访问theMethod时,流只会抱怨,这让我觉得它可能与提升有关。

我的JS foo并不是超级强者,但在这种情况下,我不认为这是相关的。箭头函数被认为是函数表达式而不是声明,因此不会被提升。我还确认如果我使用es5样式函数表达式而不是箭头函数,行为是相同的。

那是什么给出的?我错过了一些流程细化规则,误解了JS,还是Flow错了?

谢谢!

1 个答案:

答案 0 :(得分:1)

Flow不知道int main () { const char *TOKEN; char *cmd; TOKEN = "some auth token"; cmd = malloc(strlen(TOKEN) + sizeof("some_cmd --auth-token=%s") + 1; sprintf(cmd, "some_cmd --auth-token=%s", TOKEN); printf(cmd); free(cmd); } 何时会调用其回调,因此无法确定another在运行回调时是否未为空。解决此问题的一种方法是将theArgthing中取出,然后从回调中返回theArg。这样,非null thing会绑定在回调的范围内:

Try

thing