Skip to content

Commit 259853e

Browse files
cartantbenlesh
authored andcommitted
fix(types): add Boolean signature to filter (#4961)
* fix(types): add Boolean signature to filter Closes #4959 * chore: add test using comment snippet #4959 (comment) #4968
1 parent 7606dc7 commit 259853e

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

spec-dtslint/operators/filter-spec.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { of } from 'rxjs';
2-
import { filter } from 'rxjs/operators';
1+
import { Observable, of } from 'rxjs';
2+
import { filter, map } from 'rxjs/operators';
33

44
it('should support a predicate', () => {
55
const o = of(1, 2, 3).pipe(filter(value => value < 3)); // $ExpectType Observable<number>
@@ -38,3 +38,22 @@ it('should enforce user-defined type guard types', () => {
3838
const o = of(1, 2, 3).pipe(filter((value: string): value is '1' => value < '3')); // $ExpectError
3939
const p = of(1, 2, 3).pipe(filter((value: number, index): value is 1 => index < '3')); // $ExpectError
4040
});
41+
42+
it('should support Boolean as a predicate', () => {
43+
const o = of(1, 2, 3).pipe(filter(Boolean)); // $ExpectType Observable<number>
44+
const p = of(1, null, undefined).pipe(filter(Boolean)); // $ExpectType Observable<number>
45+
const q = of(null, undefined).pipe(filter(Boolean)); // $ExpectType Observable<never>
46+
});
47+
48+
// I've not been able to effect a failing dtslint test for this situation and a
49+
// conventional test won't fail because the TypeScript configuration isn't
50+
// sufficiently strict:
51+
// https://github.com/ReactiveX/rxjs/issues/4959#issuecomment-520629091
52+
it('should support inference from a return type with Boolean as a predicate', () => {
53+
interface I {
54+
a: string | null;
55+
}
56+
57+
const i$: Observable<I> = of();
58+
const s$: Observable<string> = i$.pipe(map(i => i.a), filter(Boolean)); // $ExpectType Observable<string>
59+
});

spec/operators/filter-spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,13 @@ describe('filter operator', () => {
330330

331331
// tslint:disable enable
332332
});
333+
334+
it('should support Boolean as a predicate', () => {
335+
const source = hot('-t--f--^-t-f-t-f--t-f--f--|', { t: 1, f: 0 });
336+
const subs = '^ !';
337+
const expected = '--t---t----t-------|';
338+
339+
expectObservable(source.pipe(filter(Boolean))).toBe(expected, { t: 1, f: 0 });
340+
expectSubscriptions(source.subscriptions).toBe(subs);
341+
});
333342
});

src/internal/operators/filter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Observable } from '../Observable';
44
import { OperatorFunction, MonoTypeOperatorFunction, TeardownLogic } from '../types';
55

66
/* tslint:disable:max-line-length */
7+
export function filter<T>(predicate: BooleanConstructor): OperatorFunction<T, NonNullable<T>>;
78
export function filter<T, S extends T>(predicate: (value: T, index: number) => value is S,
89
thisArg?: any): OperatorFunction<T, S>;
910
export function filter<T>(predicate: (value: T, index: number) => boolean,

0 commit comments

Comments
 (0)