流量0.74.0
该代码可在flow基于网络的REPL here
上找到 Flow在theMethod
函数内的以下语句中标记错误:another(() => theArg.thing)
:
无法获取
中缺少属性theArg.thing
,因为null或undefinedthing
代码:
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错了?
谢谢!
答案 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
在运行回调时是否未为空。解决此问题的一种方法是将theArg
从thing
中取出,然后从回调中返回theArg
。这样,非null thing
会绑定在回调的范围内:
(Try)
thing