如何区分 TypeScript 中的通用 Observable 类型?

How do I distinguish between generic Observable types in TypeScript?

我正在尝试遵循此 example in learning switchMap for rxjs. The running example is here 并用 TypeScript 编写。我试图在 VS Code 中使用 TypeScript (Angular 2) 编写类似的代码,但出现编译器错误。

Operator '+' cannot be applied to types 
'Observable | Observable' and 
'Observable | Observable'.
(parameter) curr: Observable | Observable 

我的代码如下

playSubject = new Subject<boolean>();
pauseSubject = new Subject<boolean>();
interval$  = Observable.interval(1000).mapTo(-1);
pause$ = Observable.from(this.pauseSubject).mapTo(Observable.of(false));
resume$ = Observable.from(this.playSubject).mapTo(this.interval$);
timer$ = Observable
  .merge(this.pause$, this.resume$)
  .startWith(this.interval$)
  .switchMap(v => Observable.of(v))
  .scan((acc, curr) => {
    return curr ? curr + acc : acc; //problem right here
  });
ngAfterViewInit() {
  this.timer$.subscribe(data => {
    console.log(data);
  });
}
play() { //bound to button click event
  this.playSubject.next(true);
}
pause() { //bound to button click event
  this.pauseSubject.next(false);
}

我可以修改 scan 函数中的代码如下,但是我需要知道 currObservable<boolean> 还是 Observable<number>

playSubject = new Subject<boolean>();
pauseSubject = new Subject<boolean>();
interval$  = Observable.interval(1000).mapTo(-1);
pause$ = Observable.from(this.pauseSubject).mapTo(Observable.of(false));
resume$ = Observable.from(this.playSubject).mapTo(this.interval$);
timer$ = Observable
  .merge(this.pause$, this.resume$)
  .startWith(this.interval$)
  .switchMap(v => Observable.of(v))
  .scan((acc, curr) => {
    return curr; //how do i check for Observable<Type>?
  });

知道我做错了什么或如何检查 scan 中的 Observable 类型吗?

我认为要在 VS Code 中正确修复此问题,您需要使用泛型类型参数为转译器提供以下帮助:

timer$ = Observable
  .merge(this.pause$, this.resume$)
  .startWith(this.interval$)
  .switchMap<Observable<boolean> | Observable<number>, boolean | number>(v => v)
  .scan<boolean | number, number>((acc, curr) => {
    return curr && typeof curr === "number" ? curr + acc : acc;
  }, 60);

所以这告诉转译器 switchMap 的输入是 Observable<boolean>Observable<number> 并且它的输出是 booleannumber.

然后我们告诉 scan 方法它的输入是 booleannumber 并且它的种子值的类型是 number.

我们并没有就此打住,因为这仍然会在遇到 curr + acc 表达式时混淆转译器。这是因为 curr 的类型是 boolean | numberacc 的类型是 number.

为此,我在三元运算符中引入了一个附加条件:typeof curr === "number",它使转译器满意并且代码将转译。这是有效的,因为一个名为:type guards.

的功能

另请注意,Observable.ofswitchMap 中不是必需的。