diff --git a/spec-dtslint/operators/filter-spec.ts b/spec-dtslint/operators/filter-spec.ts index bcfdddff5f..c307c39aca 100644 --- a/spec-dtslint/operators/filter-spec.ts +++ b/spec-dtslint/operators/filter-spec.ts @@ -1,5 +1,5 @@ -import { of } from 'rxjs'; -import { filter } from 'rxjs/operators'; +import { Observable, of } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; it('should support a predicate', () => { const o = of(1, 2, 3).pipe(filter(value => value < 3)); // $ExpectType Observable @@ -38,3 +38,22 @@ it('should enforce user-defined type guard types', () => { const o = of(1, 2, 3).pipe(filter((value: string): value is '1' => value < '3')); // $ExpectError const p = of(1, 2, 3).pipe(filter((value: number, index): value is 1 => index < '3')); // $ExpectError }); + +it('should support Boolean as a predicate', () => { + const o = of(1, 2, 3).pipe(filter(Boolean)); // $ExpectType Observable + const p = of(1, null, undefined).pipe(filter(Boolean)); // $ExpectType Observable + const q = of(null, undefined).pipe(filter(Boolean)); // $ExpectType Observable +}); + +// I've not been able to effect a failing dtslint test for this situation and a +// conventional test won't fail because the TypeScript configuration isn't +// sufficiently strict: +// https://github.com/ReactiveX/rxjs/issues/4959#issuecomment-520629091 +it('should support inference from a return type with Boolean as a predicate', () => { + interface I { + a: string | null; + } + + const i$: Observable = of(); + const s$: Observable = i$.pipe(map(i => i.a), filter(Boolean)); // $ExpectType Observable +}); \ No newline at end of file diff --git a/spec/operators/filter-spec.ts b/spec/operators/filter-spec.ts index 01c46b6dc1..5ca1a72469 100644 --- a/spec/operators/filter-spec.ts +++ b/spec/operators/filter-spec.ts @@ -330,4 +330,13 @@ describe('filter operator', () => { // tslint:disable enable }); + + it('should support Boolean as a predicate', () => { + const source = hot('-t--f--^-t-f-t-f--t-f--f--|', { t: 1, f: 0 }); + const subs = '^ !'; + const expected = '--t---t----t-------|'; + + expectObservable(source.pipe(filter(Boolean))).toBe(expected, { t: 1, f: 0 }); + expectSubscriptions(source.subscriptions).toBe(subs); + }); }); diff --git a/src/internal/operators/filter.ts b/src/internal/operators/filter.ts index 953aacc3b2..0cae0242d2 100644 --- a/src/internal/operators/filter.ts +++ b/src/internal/operators/filter.ts @@ -4,6 +4,7 @@ import { Observable } from '../Observable'; import { OperatorFunction, MonoTypeOperatorFunction, TeardownLogic } from '../types'; /* tslint:disable:max-line-length */ +export function filter(predicate: BooleanConstructor): OperatorFunction>; export function filter(predicate: (value: T, index: number) => value is S, thisArg?: any): OperatorFunction; export function filter(predicate: (value: T, index: number) => boolean,