我有一个Maybe(nullable)类型的数组,我想过滤那些null
'以使数组只包含非空值:
@flow
type Foo = {
foo: string
}
const bar: Array<?Foo> = [ null, { foo: 'Qux' } ]
const baz = bar
.filter(x => x != null)
.map(({ foo }) => foo);
然而,流程抱怨论证仍然是null
,而它显然不能:
11: .map(({ foo }) => foo);
^ property `foo`. Property cannot be accessed on possibly null value
请参阅flow.org/try上的代码。
有没有办法告诉流量数组现在只包含不可为空的项目?
这会破坏我的JavaScript编程功能。
答案 0 :(得分:4)
快速回答
使用.filter(Boolean)
过滤null
const baz = bar
.filter(Boolean) // <- This is the trick
.map(({ foo }) => foo);
检查传递flow.org/try。
解释(有点)
流程很难理解filter
回调中发生的情况,结果是如何获得的,以及是否真的删除了所有null
值。因此,它假设过滤后数组的类型相同;实际上它是正确的,它只能是数组的一个子集,因此是该类型的子集。
相反,由于它的工作方式,reduce
创建了一个完全不同的结构,必须推断出哪种类型(flow.org/try):
const baz = bar
.reduce((prev, next) => next == null ? prev : [...prev, next], [])
.map(({foo}) => foo);
但是,此用例非常常见,以至于流程在its code中包含例外:
filter(callbackfn: typeof Boolean): Array<$NonMaybeType<T>>;
filter(callbackfn: (value: T, index: number, array: $ReadOnlyArray<T>) => any, thisArg?: any): Array<T>;
这意味着,如果(并且仅当)Boolean
作为回调传递,则生成的数组将具有类型Array<$NonMaybeType<T>>
。 Boolean
肯定会删除null
(和undefined
)并且可以信任。