Skip to content

Commit

Permalink
fix(typescript): Update typings for race to support proper return typ…
Browse files Browse the repository at this point in the history
…es (#4465)

* fix(typescript): Update typings for race to support proper return types

* fixup! fix(typescript): Update typings for race to support proper return types
  • Loading branch information
benlesh authored Jan 14, 2019
1 parent 0118f4a commit 0042846
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 13 deletions.
59 changes: 55 additions & 4 deletions spec-dtslint/observables/race-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,68 @@ import { race, of } from 'rxjs';

it('should infer correctly with 1 parameter', () => {
const a = of(1);
const res = race(a); // $ExpectType Observable<number>
const o = race(a); // $ExpectType Observable<number>
});

it('should infer correctly with multiple parameters of the same type', () => {
const a = of(1);
const b = of(2);
const res = race(a, b); // $ExpectType Observable<number>
const o = race(a, b); // $ExpectType Observable<number>
});

it('should not support multiple parameters with different type', () => {
it('should support 2 parameters with different types', () => {
const a = of(1);
const b = of('a');
const res = race(a, b); // $ExpectError
const o = race(a, b); // $ExpectType Observable<string> | Observable<number>
});

it('should support 3 parameters with different types', () => {
const a = of(1);
const b = of('a');
const c = of(true);
const o = race(a, b, c); // $ExpectType Observable<string> | Observable<number> | Observable<boolean>
});

it('should support 4 parameters with different types', () => {
const a = of(1);
const b = of('a');
const c = of(true);
const d = of([1, 2, 3]);
const o = race(a, b, c, d); // $ExpectType Observable<string> | Observable<number> | Observable<boolean> | Observable<number[]>
});

it('should support 5 parameters with different types', () => {
const a = of(1);
const b = of('a');
const c = of(true);
const d = of([1, 2, 3]);
const e = of(['blah']);
const o = race(a, b, c, d, e); // $ExpectType Observable<string> | Observable<number> | Observable<boolean> | Observable<number[]> | Observable<string[]>
});

it('should support 6 or more parameters of the same type', () => {
const a = of(1);
const o = race(a, a, a, a, a, a, a, a, a, a, a, a, a, a); // $ExpectType Observable<number>
});

it('should return {} for 6 or more arguments of different types', () => {
const a = of(1);
const b = of('a');
const c = of(true);
const d = of([1, 2, 3]);
const e = of(['blah']);
const f = of({ foo: 'bar' });
const o = race(a, b, c, d, e, f); // $ExpectType Observable<{}>
});

it('should handle an array of observables', () => {
const a = of(1);
const b = of(2);
const o = race([a, b]); // $ExpectType Observable<number>
});

it('should return {} for array of observables of different types', () => {
const a = of(1);
const b = of('test');
const o = race([a, b]); // $ExpectType Observable<{}>
});
21 changes: 15 additions & 6 deletions src/internal/observable/race.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';

export function race<T>(observables: Array<Observable<T>>): Observable<T>;
export function race<T>(observables: Array<Observable<any>>): Observable<T>;
export function race<T>(...observables: Array<Observable<T> | Array<Observable<T>>>): Observable<T>;
// tslint:disable:max-line-length
export function race<A, B>(a: Observable<A>, b: Observable<B>): Observable<A> | Observable<B>;
export function race<A, B, C>(a: Observable<A>, b: Observable<B>, c: Observable<C>): Observable<A> | Observable<B> | Observable<C>;
export function race<A, B, C, D>(a: Observable<A>, b: Observable<B>, c: Observable<C>, d: Observable<D>): Observable<A> | Observable<B> | Observable<C> | Observable<D>;
export function race<A, B, C, D, E>(a: Observable<A>, b: Observable<B>, c: Observable<C>, d: Observable<D>, e: Observable<E>): Observable<A> | Observable<B> | Observable<C> | Observable<D> | Observable<E>;
// tslint:enable:max-line-length

export function race<T>(observables: Observable<T>[]): Observable<T>;
export function race(observables: Observable<any>[]): Observable<{}>;
export function race<T>(...observables: Observable<T>[]): Observable<T>;
export function race(...observables: Observable<any>[]): Observable<{}>;

/**
* Returns an Observable that mirrors the first source Observable to emit an item.
*
Expand All @@ -38,14 +47,14 @@ export function race<T>(...observables: Array<Observable<T> | Array<Observable<T
* @name race
* @owner Observable
*/
export function race<T>(...observables: Array<Observable<any> | Array<Observable<any>>>): Observable<T> {
export function race<T>(...observables: (Observable<any>[] | Observable<any>)[]): Observable<T> {
// if the only argument is an array, it was most likely called with
// `race([obs1, obs2, ...])`
if (observables.length === 1) {
if (isArray(observables[0])) {
observables = <Array<Observable<any>>>observables[0];
observables = observables[0] as Observable<any>[];
} else {
return <Observable<any>>observables[0];
return observables[0] as Observable<T>;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/internal/operators/race.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ export function race<T, R>(...observables: Array<Observable<any> | Array<Observa
* @owner Observable
* @deprecated Deprecated in favor of static {@link race}.
*/
export function race<T>(...observables: Array<Observable<T> | Array<Observable<T>>>): MonoTypeOperatorFunction<T> {
export function race<T>(...observables: (Observable<T> | Observable<T>[])[]): MonoTypeOperatorFunction<T> {
return function raceOperatorFunction(source: Observable<T>) {
// if the only argument is an array, it was most likely called with
// `pair([obs1, obs2, ...])`
if (observables.length === 1 && isArray(observables[0])) {
observables = <Array<Observable<T>>>observables[0];
observables = observables[0] as Observable<T>[];
}

return source.lift.call(raceStatic<T>(source, ...observables));
return source.lift.call(raceStatic(source, ...(observables as Observable<T>[])));
};
}

0 comments on commit 0042846

Please sign in to comment.