Skip to content

Commit fb9bc48

Browse files
authoredMar 15, 2019
fix(race): better typings (#4643)
- Actually accept other `ObservableInput` types (Promises, etc) - Fixes issue where TypeScript would complain when you tried to subscribe to a race between to Observable types. Fixes #4390 Fixes #4642
1 parent 8c5d831 commit fb9bc48

File tree

2 files changed

+120
-60
lines changed

2 files changed

+120
-60
lines changed
 

‎spec-dtslint/observables/race-spec.ts

+101-50
Original file line numberDiff line numberDiff line change
@@ -5,65 +5,116 @@ it('should infer correctly with 1 parameter', () => {
55
const o = race(a); // $ExpectType Observable<number>
66
});
77

8-
it('should infer correctly with multiple parameters of the same type', () => {
9-
const a = of(1);
10-
const b = of(2);
11-
const o = race(a, b); // $ExpectType Observable<number>
12-
});
8+
describe('race(a, b, c)', () => {
9+
it('should infer correctly with multiple parameters of the same type', () => {
10+
const a = of(1);
11+
const b = of(2);
12+
const o = race(a, b); // $ExpectType Observable<number>
13+
});
1314

14-
it('should support 2 parameters with different types', () => {
15-
const a = of(1);
16-
const b = of('a');
17-
const o = race(a, b); // $ExpectType Observable<string> | Observable<number>
18-
});
15+
it('should support 2 parameters with different types', () => {
16+
const a = of(1);
17+
const b = of('a');
18+
const o = race(a, b); // $ExpectType Observable<string | number>
19+
});
1920

20-
it('should support 3 parameters with different types', () => {
21-
const a = of(1);
22-
const b = of('a');
23-
const c = of(true);
24-
const o = race(a, b, c); // $ExpectType Observable<string> | Observable<number> | Observable<boolean>
25-
});
21+
it('should support 3 parameters with different types', () => {
22+
const a = of(1);
23+
const b = of('a');
24+
const c = of(true);
25+
const o = race(a, b, c); // $ExpectType Observable<string | number | boolean>
26+
});
2627

27-
it('should support 4 parameters with different types', () => {
28-
const a = of(1);
29-
const b = of('a');
30-
const c = of(true);
31-
const d = of([1, 2, 3]);
32-
const o = race(a, b, c, d); // $ExpectType Observable<string> | Observable<number> | Observable<boolean> | Observable<number[]>
33-
});
28+
it('should support 4 parameters with different types', () => {
29+
const a = of(1);
30+
const b = of('a');
31+
const c = of(true);
32+
const d = of([1, 2, 3]);
33+
const o = race(a, b, c, d); // $ExpectType Observable<string | number | boolean | number[]>
34+
});
3435

35-
it('should support 5 parameters with different types', () => {
36-
const a = of(1);
37-
const b = of('a');
38-
const c = of(true);
39-
const d = of([1, 2, 3]);
40-
const e = of(['blah']);
41-
const o = race(a, b, c, d, e); // $ExpectType Observable<string> | Observable<number> | Observable<boolean> | Observable<number[]> | Observable<string[]>
42-
});
36+
it('should support 5 parameters with different types', () => {
37+
const a = of(1);
38+
const b = of('a');
39+
const c = of(true);
40+
const d = of([1, 2, 3]);
41+
const e = of(['blah']);
42+
const o = race(a, b, c, d, e); // $ExpectType Observable<string | number | boolean | number[] | string[]>
43+
});
4344

44-
it('should support 6 or more parameters of the same type', () => {
45-
const a = of(1);
46-
const o = race(a, a, a, a, a, a, a, a, a, a, a, a, a, a); // $ExpectType Observable<number>
45+
it('should support 6 or more parameters of the same type', () => {
46+
const a = of(1);
47+
const o = race(a, a, a, a, a, a, a, a, a, a, a, a, a, a); // $ExpectType Observable<number>
48+
});
49+
50+
it('should return {} for 6 or more arguments of different types', () => {
51+
const a = of(1);
52+
const b = of('a');
53+
const c = of(true);
54+
const d = of([1, 2, 3]);
55+
const e = of(['blah']);
56+
const f = of({ foo: 'bar' });
57+
const o = race(a, b, c, d, e, f); // $ExpectType Observable<{}>
58+
});
4759
});
4860

49-
it('should return {} for 6 or more arguments of different types', () => {
50-
const a = of(1);
51-
const b = of('a');
52-
const c = of(true);
53-
const d = of([1, 2, 3]);
54-
const e = of(['blah']);
55-
const f = of({ foo: 'bar' });
56-
const o = race(a, b, c, d, e, f); // $ExpectType Observable<{}>
61+
describe('race([a, b, c])', () => {
62+
it('should infer correctly with multiple parameters of the same type', () => {
63+
const a = of(1);
64+
const b = of(2);
65+
const o = race([a, b]); // $ExpectType Observable<number>
66+
});
67+
68+
it('should support 2 parameters with different types', () => {
69+
const a = of(1);
70+
const b = of('a');
71+
const o = race([a, b]); // $ExpectType Observable<string | number>
72+
});
73+
74+
it('should support 3 parameters with different types', () => {
75+
const a = of(1);
76+
const b = of('a');
77+
const c = of(true);
78+
const o = race([a, b, c]); // $ExpectType Observable<string | number | boolean>
79+
});
80+
81+
it('should support 4 parameters with different types', () => {
82+
const a = of(1);
83+
const b = of('a');
84+
const c = of(true);
85+
const d = of([1, 2, 3]);
86+
const o = race([a, b, c, d]); // $ExpectType Observable<string | number | boolean | number[]>
87+
});
88+
89+
it('should support 5 parameters with different types', () => {
90+
const a = of(1);
91+
const b = of('a');
92+
const c = of(true);
93+
const d = of([1, 2, 3]);
94+
const e = of(['blah']);
95+
const o = race([a, b, c, d, e]); // $ExpectType Observable<string | number | boolean | number[] | string[]>
96+
});
97+
98+
it('should support 6 or more parameters of the same type', () => {
99+
const a = of(1);
100+
const o = race([a, a, a, a, a, a, a, a, a, a, a, a, a, a]); // $ExpectType Observable<number>
101+
});
102+
103+
it('should return {} for 6 or more arguments of different types', () => {
104+
const a = of(1);
105+
const b = of('a');
106+
const c = of(true);
107+
const d = of([1, 2, 3]);
108+
const e = of(['blah']);
109+
const f = of({ foo: 'bar' });
110+
const o = race([a, b, c, d, e, f]); // $ExpectType Observable<{}>
111+
});
57112
});
58113

59-
it('should handle an array of observables', () => {
60-
const a = of(1);
61-
const b = of(2);
62-
const o = race([a, b]); // $ExpectType Observable<number>
114+
it('should race observable inputs', () => {
115+
const o = race(of(1), Promise.resolve('foo'), [true, false]); // $ExpectType Observable<string | number | boolean>
63116
});
64117

65-
it('should return {} for array of observables of different types', () => {
66-
const a = of(1);
67-
const b = of('test');
68-
const o = race([a, b]); // $ExpectType Observable<{}>
118+
it('should race an array observable inputs', () => {
119+
const o = race([of(1), Promise.resolve('foo'), [true, false]]); // $ExpectType Observable<string | number | boolean>
69120
});

‎src/internal/observable/race.ts

+19-10
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,31 @@ import { fromArray } from './fromArray';
44
import { Operator } from '../Operator';
55
import { Subscriber } from '../Subscriber';
66
import { Subscription } from '../Subscription';
7-
import { TeardownLogic } from '../types';
7+
import { TeardownLogic, ObservableInput } from '../types';
88
import { OuterSubscriber } from '../OuterSubscriber';
99
import { InnerSubscriber } from '../InnerSubscriber';
1010
import { subscribeToResult } from '../util/subscribeToResult';
1111

1212
// tslint:disable:max-line-length
13-
export function race<A, B>(a: Observable<A>, b: Observable<B>): Observable<A> | Observable<B>;
14-
export function race<A, B, C>(a: Observable<A>, b: Observable<B>, c: Observable<C>): Observable<A> | Observable<B> | Observable<C>;
15-
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>;
16-
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>;
13+
export function race<A>(arg: [ObservableInput<A>]): Observable<A>;
14+
export function race<A, B>(arg: [ObservableInput<A>, ObservableInput<B>]): Observable<A | B>;
15+
export function race<A, B, C>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>]): Observable<A | B | C>;
16+
export function race<A, B, C, D>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>]): Observable<A | B | C | D>;
17+
export function race<A, B, C, D, E>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>, ObservableInput<E>]): Observable<A | B | C | D | E>;
18+
export function race<T>(arg: ObservableInput<T>[]): Observable<T>;
19+
export function race(arg: ObservableInput<any>[]): Observable<{}>;
20+
21+
export function race<A>(a: ObservableInput<A>): Observable<A>;
22+
export function race<A, B>(a: ObservableInput<A>, b: ObservableInput<B>): Observable<A | B>;
23+
export function race<A, B, C>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>): Observable<A | B | C>;
24+
export function race<A, B, C, D>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>, d: ObservableInput<D>): Observable<A | B | C | D>;
25+
export function race<A, B, C, D, E>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>, d: ObservableInput<D>, e: ObservableInput<E>): Observable<A | B | C | D | E>;
1726
// tslint:enable:max-line-length
1827

19-
export function race<T>(observables: Observable<T>[]): Observable<T>;
20-
export function race(observables: Observable<any>[]): Observable<{}>;
21-
export function race<T>(...observables: Observable<T>[]): Observable<T>;
22-
export function race(...observables: Observable<any>[]): Observable<{}>;
28+
export function race<T>(observables: ObservableInput<T>[]): Observable<T>;
29+
export function race(observables: ObservableInput<any>[]): Observable<{}>;
30+
export function race<T>(...observables: ObservableInput<T>[]): Observable<T>;
31+
export function race(...observables: ObservableInput<any>[]): Observable<{}>;
2332

2433
/**
2534
* Returns an Observable that mirrors the first source Observable to emit an item.
@@ -50,7 +59,7 @@ export function race(...observables: Observable<any>[]): Observable<{}>;
5059
* @name race
5160
* @owner Observable
5261
*/
53-
export function race<T>(...observables: (Observable<any>[] | Observable<any>)[]): Observable<T> {
62+
export function race<T>(...observables: ObservableInput<any>[]): Observable<T> {
5463
// if the only argument is an array, it was most likely called with
5564
// `race([obs1, obs2, ...])`
5665
if (observables.length === 1) {

0 commit comments

Comments
 (0)
Please sign in to comment.