最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filtering an array of Maybe (nullable) types in Flow to remove null values - Stack Overflow

programmeradmin7浏览0评论

I have an array of Maybe (nullable) type, I want to filter those null's to have an array containing only non-null values:

@flow

type Foo = {
  foo: string
}

const bar: Array<?Foo> = [ null, { foo: 'Qux' } ]

const baz = bar
  .filter(x => x != null)
  .map(({ foo }) => foo);

However, flow plains that the argument can be still null, while it clearly cannot:

11: .map(({ foo }) => foo);
            ^ property `foo`. Property cannot be accessed on possibly null value

See the code on flow/try.

Is there a way to tell flow that the array includes only non-nullable items now?

This destroys my functional JavaScript programming.

I have an array of Maybe (nullable) type, I want to filter those null's to have an array containing only non-null values:

@flow

type Foo = {
  foo: string
}

const bar: Array<?Foo> = [ null, { foo: 'Qux' } ]

const baz = bar
  .filter(x => x != null)
  .map(({ foo }) => foo);

However, flow plains that the argument can be still null, while it clearly cannot:

11: .map(({ foo }) => foo);
            ^ property `foo`. Property cannot be accessed on possibly null value

See the code on flow/try.

Is there a way to tell flow that the array includes only non-nullable items now?

This destroys my functional JavaScript programming.

Share Improve this question asked May 23, 2017 at 9:55 Robin PokornyRobin Pokorny 10.7k1 gold badge25 silver badges32 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 12

Quick answer

Use .filter(Boolean) to filter null's.

const baz = bar
  .filter(Boolean) // <- This is the trick
  .map(({ foo }) => foo);

Check it passing on flow/try.

Explanation (sort of)

It is difficult for flow to understand what happens in the filter callback, how the result was obtained, and if really all null values were removed. Therefore it assumes that the type of array is the same after filtering; which in fact is correct, it can only be a subset of the array and hence a subset of the type.

In contrast, because of the way it works, reduce creates a totally different structure for which type has to be inferred (flow/try):

const baz = bar
  .reduce((prev, next) => next == null ? prev : [...prev, next], [])
  .map(({foo}) => foo);

However, this use case is so mon that flow includes an exception in its code:

filter(callbackfn: typeof Boolean): Array<$NonMaybeType<T>>;
filter(callbackfn: (value: T, index: number, array: $ReadOnlyArray<T>) => any, thisArg?: any): Array<T>;

That means, that if (and only if) Boolean is passed as the callback the resulting array will have type Array<$NonMaybeType<T>>. Boolean will surely remove null (and undefined) and can be trusted.

发布评论

评论列表(0)

  1. 暂无评论