diff --git a/spec-dtslint/operators/exhaust-spec.ts b/spec-dtslint/operators/exhaust-spec.ts index 85c72c7390..e4ffc3d145 100644 --- a/spec-dtslint/operators/exhaust-spec.ts +++ b/spec-dtslint/operators/exhaust-spec.ts @@ -8,3 +8,14 @@ it('should infer correctly', () => { it('should enforce types', () => { const o = of(1, 2, 3).pipe(exhaust()); // $ExpectError }); + +// TODO(benlesh): The following test fails for TypeScript 3.1, but passes in TypeScript 3.2 +// I'm unsure what we need to do to get this so it ignores the TS 3.1 failure, as that's a bug +// in TypeScript, and this is properly typed now. + +// it('should support union types', () => { +// const a = Math.random() > 0.5 ? of(123) : of('abc'); +// const b = Math.random() > 0.5 ? of(123) : of('abc'); +// const source = of(a, b); +// const o = source.pipe(exhaust()); // $ExpectType Observable +// }); diff --git a/spec-dtslint/operators/exhaustMap-spec.ts b/spec-dtslint/operators/exhaustMap-spec.ts index 47f9114cef..c82dae6606 100644 --- a/spec-dtslint/operators/exhaustMap-spec.ts +++ b/spec-dtslint/operators/exhaustMap-spec.ts @@ -29,6 +29,10 @@ it('should support an undefined resultSelector', () => { const o = of(1, 2, 3).pipe(exhaustMap(p => of(Boolean(p)), undefined)); // $ExpectType Observable }); +it('should report projections to union types', () => { + const o = of(Math.random()).pipe(exhaustMap(n => n > 0.5 ? of('life') : of(42))); // $ExpectType Observable +}); + it('should enforce types', () => { const o = of(1, 2, 3).pipe(exhaustMap()); // $ExpectError }); diff --git a/src/internal/operators/exhaustMap.ts b/src/internal/operators/exhaustMap.ts index acecff4029..f54f59bc8f 100644 --- a/src/internal/operators/exhaustMap.ts +++ b/src/internal/operators/exhaustMap.ts @@ -5,14 +5,14 @@ import { Subscription } from '../Subscription'; import { OuterSubscriber } from '../OuterSubscriber'; import { InnerSubscriber } from '../InnerSubscriber'; import { subscribeToResult } from '../util/subscribeToResult'; -import { ObservableInput, OperatorFunction } from '../types'; +import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types'; import { map } from './map'; import { from } from '../observable/from'; /* tslint:disable:max-line-length */ -export function exhaustMap(project: (value: T, index: number) => ObservableInput): OperatorFunction; +export function exhaustMap>(project: (value: T, index: number) => O): OperatorFunction>; /** @deprecated resultSelector is no longer supported. Use inner map instead. */ -export function exhaustMap(project: (value: T, index: number) => ObservableInput, resultSelector: undefined): OperatorFunction; +export function exhaustMap>(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction>; /** @deprecated resultSelector is no longer supported. Use inner map instead. */ export function exhaustMap(project: (value: T, index: number) => ObservableInput, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction; /* tslint:enable:max-line-length */ @@ -59,15 +59,15 @@ export function exhaustMap(project: (value: T, index: number) => Observ * @method exhaustMap * @owner Observable */ -export function exhaustMap( - project: (value: T, index: number) => ObservableInput, - resultSelector?: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R, -): OperatorFunction { +export function exhaustMap>( + project: (value: T, index: number) => O, + resultSelector?: (outerValue: T, innerValue: ObservedValueOf, outerIndex: number, innerIndex: number) => R, +): OperatorFunction|R> { if (resultSelector) { // DEPRECATED PATH return (source: Observable) => source.pipe( exhaustMap((a, i) => from(project(a, i)).pipe( - map((b, ii) => resultSelector(a, b, i, ii)), + map((b: any, ii: any) => resultSelector(a, b, i, ii)), )), ); }