Last active
August 29, 2015 14:18
-
-
Save gordey4doronin/10ed229bce1b64fd8b3a to your computer and use it in GitHub Desktop.
Rx. Trying to merge two streams of differents types. Flies and cutlets. It works without problems in JavaScript cause of its dynamic typing nature. But it doesn't compile in TypeScript because of generic merge<T> function type safety.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var flies = [ | |
{ | |
legs: 4, | |
wings: 2 | |
}, | |
{ | |
legs: 6, | |
wings: 4 | |
} | |
]; | |
var cutlets = [ | |
{ | |
meat: 'beef', | |
cookedLevel: 'well' | |
}, | |
{ | |
meat: 'pork', | |
cookedLevel: 'medium' | |
} | |
]; | |
var subjectFlies = new Rx.Subject(); | |
var subjectCutlets = new Rx.Subject(); | |
// GD: Works well. | |
/* | |
var source = subjectFlies.merge(subjectCutlets); | |
*/ | |
// GD: Works well too. | |
var source = Rx.Observable.merge( | |
subjectFlies, | |
subjectCutlets | |
); | |
source.subscribe(function(x) { | |
console.log(x); | |
}); | |
subjectFlies.onNext(flies[0]); | |
subjectCutlets.onNext(cutlets[0]); | |
subjectFlies.onNext(flies[1]); | |
subjectCutlets.onNext(cutlets[1]); | |
// => Object {legs: 4, wings: 2} | |
// => Object {meat: "beef", cookedLevel: "well"} | |
// => Object {legs: 6, wings: 4} | |
// => Object {meat: "pork", cookedLevel: "medium"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///<reference path="../ts/rx.all.d.ts"/> | |
interface TastyOrNot { | |
tasty: boolean; | |
} | |
interface Fly extends TastyOrNot { | |
legs: number; | |
wings: number; | |
} | |
interface Cutlet extends TastyOrNot { | |
meat: string; | |
cookedLevel: string; | |
} | |
var flies: Fly[] = [ | |
{ | |
legs: 4, | |
wings: 2, | |
tasty: false | |
}, | |
{ | |
legs: 6, | |
wings: 4, | |
tasty: false | |
} | |
]; | |
var cutlets: Cutlet[] = [ | |
{ | |
meat: 'beef', | |
cookedLevel: 'well', | |
tasty: true | |
}, | |
{ | |
meat: 'pork', | |
cookedLevel: 'medium', | |
tasty: true | |
} | |
]; | |
var subjectFlies = new Rx.Subject<Fly>(); | |
var subjectCutlets = new Rx.Subject<Cutlet>(); | |
// GD: error TS2345: Argument of type 'Subject<Cutlet>' is not assignable to parameter of type 'IPromise<Fly>' | |
/* | |
var source = subjectFlies.merge(subjectCutlets); | |
*/ | |
// GD: However it's possible to reduce streams to a common type. | |
// It may be useful when for example merging two streams of different types events, | |
// To have resulting stream of common event type for both inputs. | |
var source = Rx.Observable.merge<TastyOrNot>(subjectFlies, subjectCutlets); | |
// GD: It's also possible to force TS dynamic typing like this. | |
var sourceOfAny = Rx.Observable.merge<any>(subjectFlies, subjectCutlets); | |
source.subscribe(function(x) { | |
console.log(x); | |
}); | |
subjectFlies.onNext(flies[0]); | |
subjectCutlets.onNext(cutlets[0]); | |
subjectFlies.onNext(flies[1]); | |
subjectCutlets.onNext(cutlets[1]); | |
// => Object {legs: 4, wings: 2, tasty: false} | |
// => Object {meat: "beef", cookedLevel: "well", tasty: true} | |
// => Object {legs: 6, wings: 4, tasty: false} | |
// => Object {meat: "pork", cookedLevel: "medium", tasty: true} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
JSFiddle example: http://jsfiddle.net/gdoronin/y0ogy07b/