Javascript 访问truthy检查后定义的函数表达式时出现流错误

Javascript 访问truthy检查后定义的函数表达式时出现流错误,javascript,flowtype,Javascript,Flowtype,流量0.74.0 该代码可在flow基于web的REPL上获得 Flow在theMethod函数中的以下语句上标记错误:另一个(()=>theArg.thing): 无法获取arg.thing,因为null或未定义中缺少属性thing 代码: 虽然arg已尽可能键入,method在通过真实检查之前不会访问arg 使细化无效? 由于某些方法调用可能会在truthy检查后影响arg,因此错误似乎不是流的结果 流并不是在抱怨theArg.thing可能为null/undefined,而是在抱怨theA

流量0.74.0

该代码可在flow基于web的REPL上获得

Flow在
theMethod
函数中的以下语句上标记错误:
另一个(()=>theArg.thing)

无法获取arg.thing,因为null或未定义中缺少属性
thing

代码:

虽然
arg
已尽可能键入,
method
在通过真实检查之前不会访问
arg

使细化无效? 由于某些方法调用可能会在truthy检查后影响arg,因此错误似乎不是流的结果

流并不是在抱怨
theArg.thing
可能为null/undefined,而是在抱怨
theArg
在truthy检查后可能为null/undefined。虽然外部函数可以对引用的对象进行变异,但它不能更改引用的对象

我通过直接访问
method
函数体中的
arg
再次检查了这个期望:
console.log('in theMethod',theArg.thing')aFunc
)后的代码>。这没问题

吊起 Flow只在我访问Method
中的函数表达式内部的Arg时才会抱怨,这使我认为它可能与提升有关

我的JS-foo不是超级强大,但我认为这与本例无关。arrow函数被认为是一个函数表达式,而不是一个声明,因此它不会被提升。我还确认,如果我使用es5样式的函数表达式而不是箭头函数,则行为是相同的

那么是什么原因呢?我是否遗漏了一些流优化规则,误解了JS,或者流是错误的


谢谢

流不知道另一个
将在何时调用其回调,因此无法确定在运行回调时,
arg
是否已变为null。解决这个问题的一种方法是将
thing
arg
中取出,然后从回调返回
thing
。这样,非null的
对象
被绑定在回调的范围内:

()


詹姆斯,这是有道理的。Flow正在进行保守/防御评估,因为另一个
可能会在任何时候调用该箭头函数。每次我想我已经习惯了JS以回调为中心的特性,它就会再一次咬我的屁股。谢谢
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);
}
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);

  // Now flow knows thing isn't null
  const {thing} = theArg
  another(() => thing);
}