2017-10-04 31 views
1

您可以在flow.org/try查看代码,或者你可以看它在这里:流量甚至类型细化后抱怨未定义

/* @flow */ 

type Thing = { 
    arr?: Array<number> 
} 

const thing: Thing = { 
    arr: [10, 20, 30] 
} 

function getSubArray(thing: Thing, index: number) { 
    if (!thing.arr) return [] 

    return [ 
    ...thing.arr.slice(0, index), 
    ...thing.arr.slice(index + 1) 
    ] 
} 

const newArr = getSubArray(thing, 1) 

我认为做if (!thing.arr) return [],将作为“类型精化”和流理解thing.arr之后不是undefined。然而,它给我一个错误说

16:  ...thing.arr.slice(index + 1)   
     ^call of method `slice`. Method cannot be called on possibly undefined value 
16:  ...thing.arr.slice(index + 1) 
     ^undefined 

任何帮助,将不胜感激!

+0

当您删除数组文本中的第二个传播操作时,它会输入检查。我想这个第一次操作无论如何都会使优化无效。在所有情况下,使用Javascript正确推断类型可能很难或不可能,因为副作用可以在任何地方逐字执行。 – ftor

+0

是的,我也注意到了。你认为解决这个问题的唯一方法是使用[类型转换](https://flow.org/en/docs/types/casting/)? – saadq

回答

1

第一次致电arr.slice“可能”变异thing.arr变为undefined,使得第二次调用slice出现错误。流程通过使细化无效来保护您免受这种可能性的影响。

您可以将thing.arr存储在const中,然后使用它(在所有三个位置)来避免潜在的错误。

+0

但是'slice'是内置的,不会改变任何东西。不应该流动知道行为不可变的内置函数吗? – ftor

+0

请参阅https://github.com/facebook/flow/issues/4941 https://github.com/facebook/flow/issues/4458 https://github.com/facebook/flow/issues/3059 https:/ /github.com/facebook/flow/issues/2986 https://github.com/facebook/flow/issues/2728等 –

+0

唉,这是很多需要阅读的。所有这些问题归结为_Flow只能做到这一点,而不会变成运行时引擎_。 – ftor

相关问题