如何区分 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
函数中的代码如下,但是我需要知道 curr
是 Observable<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>
并且它的输出是 boolean
或 number
.
然后我们告诉 scan
方法它的输入是 boolean
或 number
并且它的种子值的类型是 number
.
我们并没有就此打住,因为这仍然会在遇到 curr + acc
表达式时混淆转译器。这是因为 curr
的类型是 boolean | number
而 acc
的类型是 number
.
为此,我在三元运算符中引入了一个附加条件:typeof curr === "number"
,它使转译器满意并且代码将转译。这是有效的,因为一个名为:type guards.
的功能
另请注意,Observable.of
在 switchMap
中不是必需的。
我正在尝试遵循此 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
函数中的代码如下,但是我需要知道 curr
是 Observable<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>
并且它的输出是 boolean
或 number
.
然后我们告诉 scan
方法它的输入是 boolean
或 number
并且它的种子值的类型是 number
.
我们并没有就此打住,因为这仍然会在遇到 curr + acc
表达式时混淆转译器。这是因为 curr
的类型是 boolean | number
而 acc
的类型是 number
.
为此,我在三元运算符中引入了一个附加条件:typeof curr === "number"
,它使转译器满意并且代码将转译。这是有效的,因为一个名为:type guards.
另请注意,Observable.of
在 switchMap
中不是必需的。