diff --git a/spec-dtslint/observables/zip-spec.ts b/spec-dtslint/observables/zip-spec.ts index 19c21a71db..e37976e469 100644 --- a/spec-dtslint/observables/zip-spec.ts +++ b/spec-dtslint/observables/zip-spec.ts @@ -36,3 +36,14 @@ it('should return Array when given a single observable', () => { const a = of(1); // $ExpectType Observable const o1 = zip(a); // $ExpectType Observable }); + +it('should support union types', () => { + const u = Math.random() > 0.5 ? of(123) : of('abc'); + const o = zip(u, u, u); // $ExpectType Observable<[string | number, string | number, string | number]> +}); + +it('should support different union types', () => { + const u = Math.random() > 0.5 ? of(123) : of('abc'); + const u2 = Math.random() > 0.5 ? of(true) : of([1, 2, 3]); + const o = zip(u, u2); // $ExpectType Observable<[string | number, boolean | number[]]> +}); diff --git a/src/internal/observable/zip.ts b/src/internal/observable/zip.ts index f360913742..b32965bb34 100644 --- a/src/internal/observable/zip.ts +++ b/src/internal/observable/zip.ts @@ -2,7 +2,7 @@ import { Observable } from '../Observable'; import { fromArray } from './fromArray'; import { isArray } from '../util/isArray'; import { Operator } from '../Operator'; -import { ObservableInput, PartialObserver } from '../types'; +import { ObservableInput, PartialObserver, ObservedValueOf } from '../types'; import { Subscriber } from '../Subscriber'; import { Subscription } from '../Subscription'; import { OuterSubscriber } from '../OuterSubscriber'; @@ -12,33 +12,33 @@ import { iterator as Symbol_iterator } from '../../internal/symbol/iterator'; /* tslint:disable:max-line-length */ /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, resultSelector: (v1: T) => R): Observable; +export function zip, R>(v1: O1, resultSelector: (v1: ObservedValueOf) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, v2: ObservableInput, resultSelector: (v1: T, v2: T2) => R): Observable; +export function zip, O2 extends ObservableInput, R>(v1: O1, v2: O2, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, resultSelector: (v1: T, v2: T2, v3: T3) => R): Observable; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, R>(v1: O1, v2: O2, v3: O3, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf, v3: ObservedValueOf) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4) => R): Observable; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput, R>(v1: O1, v2: O2, v3: O3, v4: O4, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf, v3: ObservedValueOf, v4: ObservedValueOf) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput, v5: ObservableInput, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => R): Observable; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput, O5 extends ObservableInput, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf, v3: ObservedValueOf, v4: ObservedValueOf, v5: ObservedValueOf) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput, v5: ObservableInput, v6: ObservableInput, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => R): Observable; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput, O5 extends ObservableInput, O6 extends ObservableInput, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, resultSelector: (v1: ObservedValueOf, v2: ObservedValueOf, v3: ObservedValueOf, v4: ObservedValueOf, v5: ObservedValueOf, v6: ObservedValueOf) => R): Observable; -export function zip(v1: ObservableInput, v2: ObservableInput): Observable<[T, T2]>; -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput): Observable<[T, T2, T3]>; -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput): Observable<[T, T2, T3, T4]>; -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput, v5: ObservableInput): Observable<[T, T2, T3, T4, T5]>; -export function zip(v1: ObservableInput, v2: ObservableInput, v3: ObservableInput, v4: ObservableInput, v5: ObservableInput, v6: ObservableInput): Observable<[T, T2, T3, T4, T5, T6]>; +export function zip, O2 extends ObservableInput>(v1: O1, v2: O2): Observable<[ObservedValueOf, ObservedValueOf]>; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput>(v1: O1, v2: O2, v3: O3): Observable<[ObservedValueOf, ObservedValueOf, ObservedValueOf]>; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput>(v1: O1, v2: O2, v3: O3, v4: O4): Observable<[ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf]>; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput, O5 extends ObservableInput>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5): Observable<[ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf]>; +export function zip, O2 extends ObservableInput, O3 extends ObservableInput, O4 extends ObservableInput, O5 extends ObservableInput, O6 extends ObservableInput>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): Observable<[ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf, ObservedValueOf]>; -export function zip(array: ObservableInput[]): Observable; +export function zip>(array: O[]): Observable[]>; export function zip(array: ObservableInput[]): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(array: ObservableInput[], resultSelector: (...values: Array) => R): Observable; +export function zip, R>(array: O[], resultSelector: (...values: ObservedValueOf[]) => R): Observable; /** @deprecated resultSelector is no longer supported, pipe to map instead */ -export function zip(array: ObservableInput[], resultSelector: (...values: Array) => R): Observable; +export function zip(array: ObservableInput[], resultSelector: (...values: any[]) => R): Observable; -export function zip(...observables: Array>): Observable; -export function zip(...observables: Array | ((...values: Array) => R)>): Observable; +export function zip>(...observables: O[]): Observable[]>; +export function zip, R>(...observables: Array[]) => R)>): Observable; export function zip(...observables: Array | ((...values: Array) => R)>): Observable; /* tslint:enable:max-line-length */ @@ -72,7 +72,9 @@ export function zip(...observables: Array | ((...values: * @name zip * @owner Observable */ -export function zip(...observables: Array | ((...values: Array) => R)>): Observable { +export function zip, R>( + ...observables: Array[]) => R)> +): Observable[]|R> { const resultSelector = <((...ys: Array) => R)> observables[observables.length - 1]; if (typeof resultSelector === 'function') { observables.pop();