【问题标题】:How do I distinguish between generic Observable types in TypeScript?如何区分 TypeScript 中的通用 Observable 类型?
【发布时间】:2017-01-31 13:26:35
【问题描述】:

我正在尝试跟随这个example 学习switchMaprxjs。正在运行的示例是here,并用 TypeScript 编写。我尝试在 VS Code 的 TypeScript (Angular 2) 中编写类似的代码,但出现编译器错误。

运算符“+”不能应用于类型 '可观察 |可观察的'和 '可观察 |可观察”。 (参数) curr: 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&lt;boolean&gt;还是Observable&lt;number&gt;

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 类型吗?

【问题讨论】:

  • 投票结束的原因是什么?
  • 为什么在switchMap 中使用Observable.of?您提供的示例没有。
  • 如果我不这样做,我会在 VS Code 中得到一个编译错误。请注意,该示例使用 TypeScript,但将其复制/粘贴到 VS Code(在 Angular 2 项目中)不起作用。
  • .startWith(this.interval$) 中的问题不是您从 Observable 开始序列吗?操作员 startWith 只是按原样重新发送 Observable 而不订阅它 reactivex.io/rxjs/file/es6/operator/…
  • 这是怎么回事?我几乎一字不差地从 learnrxjs.io 获取了这段代码。

标签: angular typescript rxjs rxjs5 typescript2.0


【解决方案1】:

我认为要在 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&lt;boolean&gt;Observable&lt;number&gt;,其输出是booleannumber

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

我们不会在这里停下来,因为当它遇到curr + acc 表达式时,它仍然会混淆转译器。这是因为curr 的类型是boolean | numberacc 的类型是number

为此,我在三元运算符中引入了一个附加条件:typeof curr === "number",这使转译器很高兴,并且代码将转译。这是因为一个名为type guards的功能。

还要注意Observable.ofswitchMap 中不是必需的。

【讨论】:

    猜你喜欢
    • 2017-10-27
    • 2020-07-29
    • 2017-04-10
    • 1970-01-01
    • 2021-03-26
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    相关资源
    最近更新 更多