Skip to content

Commit fb9bc48

Browse files
authored
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#4390Fixes#4642
1 parent 8c5d831 commit fb9bc48

2 files changed

Lines changed: 120 additions & 60 deletions

File tree

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

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

8-
it('should infer correctly with multiple parameters of the same type',()=>{
9-
consta=of(1);
10-
constb=of(2);
11-
consto=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+
consta=of(1);
11+
constb=of(2);
12+
consto=race(a,b);// $ExpectType Observable<number>
13+
});
1314

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

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

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

35-
it('should support 5 parameters with different types',()=>{
36-
consta=of(1);
37-
constb=of('a');
38-
constc=of(true);
39-
constd=of([1,2,3]);
40-
conste=of(['blah']);
41-
consto=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+
consta=of(1);
38+
constb=of('a');
39+
constc=of(true);
40+
constd=of([1,2,3]);
41+
conste=of(['blah']);
42+
consto=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-
consta=of(1);
46-
consto=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+
consta=of(1);
47+
consto=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+
consta=of(1);
52+
constb=of('a');
53+
constc=of(true);
54+
constd=of([1,2,3]);
55+
conste=of(['blah']);
56+
constf=of({foo: 'bar'});
57+
consto=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-
consta=of(1);
51-
constb=of('a');
52-
constc=of(true);
53-
constd=of([1,2,3]);
54-
conste=of(['blah']);
55-
constf=of({foo: 'bar'});
56-
consto=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+
consta=of(1);
64+
constb=of(2);
65+
consto=race([a,b]);// $ExpectType Observable<number>
66+
});
67+
68+
it('should support 2 parameters with different types',()=>{
69+
consta=of(1);
70+
constb=of('a');
71+
consto=race([a,b]);// $ExpectType Observable<string | number>
72+
});
73+
74+
it('should support 3 parameters with different types',()=>{
75+
consta=of(1);
76+
constb=of('a');
77+
constc=of(true);
78+
consto=race([a,b,c]);// $ExpectType Observable<string | number | boolean>
79+
});
80+
81+
it('should support 4 parameters with different types',()=>{
82+
consta=of(1);
83+
constb=of('a');
84+
constc=of(true);
85+
constd=of([1,2,3]);
86+
consto=race([a,b,c,d]);// $ExpectType Observable<string | number | boolean | number[]>
87+
});
88+
89+
it('should support 5 parameters with different types',()=>{
90+
consta=of(1);
91+
constb=of('a');
92+
constc=of(true);
93+
constd=of([1,2,3]);
94+
conste=of(['blah']);
95+
consto=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+
consta=of(1);
100+
consto=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+
consta=of(1);
105+
constb=of('a');
106+
constc=of(true);
107+
constd=of([1,2,3]);
108+
conste=of(['blah']);
109+
constf=of({foo: 'bar'});
110+
consto=race([a,b,c,d,e,f]);// $ExpectType Observable<{}>
111+
});
57112
});
58113

59-
it('should handle an array of observables',()=>{
60-
consta=of(1);
61-
constb=of(2);
62-
consto=race([a,b]);// $ExpectType Observable<number>
114+
it('should race observable inputs',()=>{
115+
consto=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-
consta=of(1);
67-
constb=of('test');
68-
consto=race([a,b]);// $ExpectType Observable<{}>
118+
it('should race an array observable inputs',()=>{
119+
consto=race([of(1),Promise.resolve('foo'),[true,false]]);// $ExpectType Observable<string | number | boolean>
69120
});

‎src/internal/observable/race.ts‎

Lines changed: 19 additions & 10 deletions
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-
exportfunctionrace<A,B>(a: Observable<A>,b: Observable<B>): Observable<A>|Observable<B>;
14-
exportfunctionrace<A,B,C>(a: Observable<A>,b: Observable<B>,c: Observable<C>): Observable<A>|Observable<B>|Observable<C>;
15-
exportfunctionrace<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-
exportfunctionrace<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+
exportfunctionrace<A>(arg: [ObservableInput<A>]): Observable<A>;
14+
exportfunctionrace<A,B>(arg: [ObservableInput<A>,ObservableInput<B>]): Observable<A|B>;
15+
exportfunctionrace<A,B,C>(arg: [ObservableInput<A>,ObservableInput<B>,ObservableInput<C>]): Observable<A|B|C>;
16+
exportfunctionrace<A,B,C,D>(arg: [ObservableInput<A>,ObservableInput<B>,ObservableInput<C>,ObservableInput<D>]): Observable<A|B|C|D>;
17+
exportfunctionrace<A,B,C,D,E>(arg: [ObservableInput<A>,ObservableInput<B>,ObservableInput<C>,ObservableInput<D>,ObservableInput<E>]): Observable<A|B|C|D|E>;
18+
exportfunctionrace<T>(arg: ObservableInput<T>[]): Observable<T>;
19+
exportfunctionrace(arg: ObservableInput<any>[]): Observable<{}>;
20+
21+
exportfunctionrace<A>(a: ObservableInput<A>): Observable<A>;
22+
exportfunctionrace<A,B>(a: ObservableInput<A>,b: ObservableInput<B>): Observable<A|B>;
23+
exportfunctionrace<A,B,C>(a: ObservableInput<A>,b: ObservableInput<B>,c: ObservableInput<C>): Observable<A|B|C>;
24+
exportfunctionrace<A,B,C,D>(a: ObservableInput<A>,b: ObservableInput<B>,c: ObservableInput<C>,d: ObservableInput<D>): Observable<A|B|C|D>;
25+
exportfunctionrace<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-
exportfunctionrace<T>(observables: Observable<T>[]): Observable<T>;
20-
exportfunctionrace(observables: Observable<any>[]): Observable<{}>;
21-
exportfunctionrace<T>(...observables: Observable<T>[]): Observable<T>;
22-
exportfunctionrace(...observables: Observable<any>[]): Observable<{}>;
28+
exportfunctionrace<T>(observables: ObservableInput<T>[]): Observable<T>;
29+
exportfunctionrace(observables: ObservableInput<any>[]): Observable<{}>;
30+
exportfunctionrace<T>(...observables: ObservableInput<T>[]): Observable<T>;
31+
exportfunctionrace(...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-
exportfunctionrace<T>(...observables: (Observable<any>[]|Observable<any>)[]): Observable<T>{
62+
exportfunctionrace<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)