Skip to content

Commit

Permalink
fix(merge): support union types
Browse files Browse the repository at this point in the history
Allows xs.merge(streamOfNumbers, streamOfStrings) to return a Stream of numbers or strings, as the return type in TypeScript.

Modifis static `merge` method to implement a new interface:
MergeSignature. This interface is constructed similarly to the
CombineSignature interface. Export the new interface.

This change allows consumers invoking the static method to declare types
and leverage TypeScript to verify type safety when merging streams. The
change brings `merge` in line with other static methods which already
include this feature.

PR #82.

Should resolve #80.
  • Loading branch information
Christian Johns authored and staltz committed Jul 20, 2016
1 parent 5cd05ed commit 5327cb0
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
38 changes: 35 additions & 3 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,37 @@ export class MergeProducer<T> implements Aggregator<T, T>, InternalListener<T> {
}
}

export interface MergeSignature {
(): Stream<any>;
<T1>(s1: Stream<T1>): Stream<T1>;
<T1, T2>(
s1: Stream<T1>,
s2: Stream<T2>): Stream<T1 | T2>;
<T1, T2, T3>(
s1: Stream<T1>,
s2: Stream<T2>,
s3: Stream<T3>): Stream<T1 | T2 | T3>;
<T1, T2, T3, T4>(
s1: Stream<T1>,
s2: Stream<T2>,
s3: Stream<T3>,
s4: Stream<T4>): Stream<T1 | T2 | T3 | T4>;
<T1, T2, T3, T4, T5>(
s1: Stream<T1>,
s2: Stream<T2>,
s3: Stream<T3>,
s4: Stream<T4>,
s5: Stream<T5>): Stream<T1 | T2 | T3 | T4 | T5>;
<T1, T2, T3, T4, T5, T6>(
s1: Stream<T1>,
s2: Stream<T2>,
s3: Stream<T3>,
s4: Stream<T4>,
s5: Stream<T5>,
s6: Stream<T6>): Stream<T1 | T2 | T3 | T4 | T5 | T6>;
<T>(...stream: Array<Stream<T>>): Stream<T>;
}

export interface CombineSignature {
(): Stream<Array<any>>;
<T1>(s1: Stream<T1>): Stream<[T1]>;
Expand Down Expand Up @@ -1377,9 +1408,10 @@ export class Stream<T> implements InternalListener<T> {
* or more streams may be given as arguments.
* @return {Stream}
*/
static merge<T>(...streams: Array<Stream<T>>): Stream<T> {
return new Stream<T>(new MergeProducer(streams));
}
static merge: MergeSignature = <MergeSignature>
function merge(...streams: Array<Stream<any>>): Stream<any> {
return new Stream<any>(new MergeProducer(streams));
};

/**
* Combines multiple input streams together to return a stream whose events
Expand Down
21 changes: 21 additions & 0 deletions tests/factory/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,25 @@ describe('xs.merge', () => {
assert.strictEqual(stream instanceof Stream, true);
done();
});

it('should have a correct TypeScript signature', () => {
const bools = xs.create<boolean>({
start: listener => {},
stop: () => {}
});

const numbers = xs.create<number>({
start: listener => {},
stop: () => {}
});

const strings = xs.create<string>({
start: listener => {},
stop: () => {}
});

const emptyIsh: Stream<boolean> = xs.merge<boolean>();
const doubled: Stream<boolean | string> = xs.merge(bools, strings);
const tripled: Stream<boolean | number | string> = xs.merge(bools, strings, numbers);
});
});

0 comments on commit 5327cb0

Please sign in to comment.