Flow doesn't recognise refinement inside callback

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

This code passes the flow check:

/* @flow */  function test (list: ?Array<string>): Promise<number> {   if(list !== null && list !== undefined) {     return Promise.resolve(list.length)   } else {     return Promise.resolve(0)   } }  console.log(test(null)) 

Whereas the following gets a null check error

/* @flow */  function test (list: ?Array<string>): Promise<number> {   if(list !== null && list !== undefined) {     return Promise.resolve().then(() => list.length)   } else {     return Promise.resolve(0)   } }  console.log(test(null)) 

error:

property `length`. Property cannot be accessed on possibly null value 

Clearly list cannot be null so there must be something about the code structure that makes flow unable to recognise this.

I would like to understand what limitation I am hitting and how I can work around it. Thanks!

回答1:

Basically, Flow doesn't know that your type refinement (null check) will hold at the time when () => list.length

The difference between first and second snippet is that in the second snippet list

One solution is to extract list.length into a variable, and use that variable in the callback.

var length = list.length; return Promise.resolve().then(() => length) 

This might also work:

var list2: Array<string> = list; return Promise.resolve().then(() => list2.length) 

Note that this problem exists even for immediately invoked callbacks, e.g. when using map or forEach. There is an issue on flow's github about this, but I couldn't find it after a quick search.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!