From 860280f2c38d615784fa393ce8c15a05a212ff0d Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Thu, 5 Oct 2017 03:39:40 -0700 Subject: [PATCH] Flow type: Add special case for `.filter(Boolean)` to remove nulls. Fixes #1200 --- type-definitions/immutable.js.flow | 85 +++++++++++++++++++++--- type-definitions/tests/immutable-flow.js | 9 +++ 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/type-definitions/immutable.js.flow b/type-definitions/immutable.js.flow index 3f32a6e929..1b2d814504 100644 --- a/type-definitions/immutable.js.flow +++ b/type-definitions/immutable.js.flow @@ -101,11 +101,6 @@ declare class _Collection /*implements ValueObject*/ { takeWhile(predicate: (value: V, key: K, iter: this) => mixed, context?: mixed): this; takeUntil(predicate: (value: V, key: K, iter: this) => mixed, context?: mixed): this; - filter( - predicate: (value: V, key: K, iter: this) => mixed, - context?: mixed - ): this; - filterNot( predicate: (value: V, key: K, iter: this) => mixed, context?: mixed @@ -217,6 +212,12 @@ declare class KeyedCollection extends Collection { concat(...iters: Array>): KeyedCollection; concat(...iters: Array>): KeyedCollection; + filter(predicate: typeof Boolean): KeyedCollection>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): KeyedCollection; + map( mapper: (value: V, key: K, iter: this) => M, context?: mixed @@ -371,6 +372,12 @@ declare class IndexedCollection<+T> extends Collection { concat(...iters: Array | C>): IndexedCollection; + filter(predicate: typeof Boolean): IndexedCollection<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): IndexedCollection; + map( mapper: (value: T, index: number, iter: this) => M, context?: mixed @@ -396,10 +403,16 @@ declare class SetCollection<+T> extends Collection { concat(...iters: Array | C>): SetCollection; - // `map` and `flatMap` cannot be defined further up the hierarchy, because the - // implementation for `KeyedCollection` allows the value type to change without - // constraining the key type. That does not work for `SetCollection` - the value - // and key types *must* match. + // `filter`, `map` and `flatMap` cannot be defined further up the hierarchy, + // because the implementation for `KeyedCollection` allows the value type to + // change without constraining the key type. That does not work for + // `SetCollection` - the value and key types *must* match. + filter(predicate: typeof Boolean): SetCollection<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): SetCollection; + map( mapper: (value: T, value: T, iter: this) => M, context?: mixed @@ -442,6 +455,12 @@ declare class KeyedSeq extends Seq mixins KeyedCollection { concat(...iters: Array>): KeyedSeq; concat(...iters: Array>): KeyedSeq; + filter(predicate: typeof Boolean): KeyedSeq>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): KeyedSeq; + map( mapper: (value: V, key: K, iter: this) => M, context?: mixed @@ -475,6 +494,12 @@ declare class IndexedSeq<+T> extends Seq mixins IndexedCollection concat(...iters: Array | C>): IndexedSeq; + filter(predicate: typeof Boolean): IndexedSeq<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): IndexedSeq; + map( mapper: (value: T, index: number, iter: this) => M, context?: mixed @@ -596,6 +621,12 @@ declare class SetSeq<+T> extends Seq mixins SetCollection { concat(...iters: Array | C>): SetSeq; + filter(predicate: typeof Boolean): SetSeq<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): SetSeq; + map( mapper: (value: T, value: T, iter: this) => M, context?: mixed @@ -663,6 +694,12 @@ declare class List<+T> extends IndexedCollection { concat(...iters: Array | C>): List; + filter(predicate: typeof Boolean): List<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): List; + map( mapper: (value: T, index: number, iter: this) => M, context?: mixed @@ -849,6 +886,12 @@ declare class Map extends KeyedCollection { concat(...iters: Array>): Map; concat(...iters: Array>): Map; + filter(predicate: typeof Boolean): Map>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): Map; + map( mapper: (value: V, key: K, iter: this) => M, context?: mixed @@ -944,6 +987,12 @@ declare class OrderedMap extends Map { concat(...iters: Array>): OrderedMap; concat(...iters: Array>): OrderedMap; + filter(predicate: typeof Boolean): OrderedMap>; + filter( + predicate: (value: V, key: K, iter: this) => mixed, + context?: mixed + ): OrderedMap; + map( mapper: (value: V, key: K, iter: this) => M, context?: mixed @@ -1001,6 +1050,12 @@ declare class Set<+T> extends SetCollection { concat(...iters: Array | C>): Set; + filter(predicate: typeof Boolean): Set<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): Set; + map( mapper: (value: T, value: T, iter: this) => M, context?: mixed @@ -1036,6 +1091,12 @@ declare class OrderedSet<+T> extends Set { concat(...iters: Array | C>): OrderedSet; + filter(predicate: typeof Boolean): OrderedSet<$NonMaybeType>; + filter( + predicate: (value: T, value: T, iter: this) => mixed, + context?: mixed + ): OrderedSet; + map( mapper: (value: T, value: T, iter: this) => M, context?: mixed @@ -1177,6 +1238,12 @@ declare class Stack<+T> extends IndexedCollection { concat(...iters: Array | C>): Stack; + filter(predicate: typeof Boolean): Stack<$NonMaybeType>; + filter( + predicate: (value: T, index: number, iter: this) => mixed, + context?: mixed + ): Stack; + map( mapper: (value: T, index: number, iter: this) => M, context?: mixed diff --git a/type-definitions/tests/immutable-flow.js b/type-definitions/tests/immutable-flow.js index ebad3c0143..c5cc9e0d20 100644 --- a/type-definitions/tests/immutable-flow.js +++ b/type-definitions/tests/immutable-flow.js @@ -196,6 +196,9 @@ numberList = List.of(1).flatMap((value, index, iter) => ['a']) numberList = List.of(1).flatten() +// Specific type for filter(Boolean) which removes nullability. +numberList = nullableNumberList.filter(Boolean) + /* Map */ stringToNumber = Map() @@ -333,6 +336,12 @@ stringToNumber = Map({'a': 1}).mapKeys((key, value, iter) => 1) anyMap = Map({'a': 1}).flatten() +var stringToNullableNumber = Map({'a': 1, 'b': null}); +// $ExpectError +stringToNumber = stringToNullableNumber; +// Specific type for filter(Boolean) which removes nullability. +stringToNumber = stringToNullableNumber.filter(Boolean) + /* OrderedMap */ orderedStringToNumber = Map({'a': 1}).toOrderedMap()