在Flow中过滤Maybe(可空)类型数组以删除空值

时间:2017-05-23 09:55:09

标签: javascript functional-programming flowtype

我有一个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编程功能。

1 个答案:

答案 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)并且可以信任。