Skip to content

Commit

Permalink
feat(filter): improve type inference for filter(Boolean)
Browse files Browse the repository at this point in the history
  • Loading branch information
josepot committed Oct 15, 2020
1 parent adbe65e commit 051ad34
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
2 changes: 1 addition & 1 deletion api_guard/dist/types/operators/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export declare function expand<T, R>(project: (value: T, index: number) => Obser
export declare function expand<T, R>(project: (value: T, index: number) => ObservableInput<R>, concurrent: number | undefined, scheduler: SchedulerLike): OperatorFunction<T, R>;

export declare function filter<T, S extends T>(predicate: (value: T, index: number) => value is S, thisArg?: any): OperatorFunction<T, S>;
export declare function filter<T>(predicate: BooleanConstructor): OperatorFunction<T | null | undefined, NonNullable<T>>;
export declare function filter<T>(predicate: BooleanConstructor): OperatorFunction<T, T extends null | undefined | false | 0 | -0 | 0n | '' ? never : T>;
export declare function filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>;

export declare function finalize<T>(callback: () => void): MonoTypeOperatorFunction<T>;
Expand Down
6 changes: 6 additions & 0 deletions spec-dtslint/operators/filter-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ it('should support Boolean as a predicate', () => {
const o = of(1, 2, 3).pipe(filter(Boolean)); // $ExpectType Observable<number>
const p = of(1, null, undefined).pipe(filter(Boolean)); // $ExpectType Observable<number>
const q = of(null, undefined).pipe(filter(Boolean)); // $ExpectType Observable<never>
const r = of(true).pipe(filter(Boolean)); // $ExpectType Observable<true>
const s = of(false as const).pipe(filter(Boolean)); // $ExpectType Observable<never>
const t = of(0 as const, -0 as const, 1 as const).pipe(filter(Boolean)); // $ExpectType Observable<1>
const u = of(0 as const, -0 as const).pipe(filter(Boolean)); // $ExpectType Observable<never>
const v = of('' as const, "foo" as const, "bar" as const).pipe(filter(Boolean)); // $ExpectType Observable<"foo" | "bar">
const w = of('' as const).pipe(filter(Boolean)); // $ExpectType Observable<never>
});

// I've not been able to effect a failing dtslint test for this situation and a
Expand Down
5 changes: 3 additions & 2 deletions src/internal/operators/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { OperatorSubscriber } from './OperatorSubscriber';

/* tslint:disable:max-line-length */
export function filter<T, S extends T>(predicate: (value: T, index: number) => value is S, thisArg?: any): OperatorFunction<T, S>;
// NOTE(benlesh): T|null|undefined solves the issue discussed here: https://github.com/ReactiveX/rxjs/issues/4959#issuecomment-520629091
export function filter<T>(predicate: BooleanConstructor): OperatorFunction<T | null | undefined, NonNullable<T>>;
export function filter<T>(
predicate: BooleanConstructor
): OperatorFunction<T, T extends null | undefined | false | 0 | -0 | 0n | '' ? never : T>;
export function filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>;
/* tslint:enable:max-line-length */

Expand Down

0 comments on commit 051ad34

Please sign in to comment.