我如何 "cache" rxjs lettable operators 并在多个 .pipe() 调用中重用它们而不破坏 TypeScript 的类型检查
How can I "cache" rxjs lettable operators and reuse them in multiple `.pipe()` calls without breaking TypeScript's type checking
(仅供参考。这是一个 Angular 5 应用程序,但这种情况本身并不是 Angular 所特有的)
我有几个运算符在不同的地方以相同的方式大量使用。为了减少重复代码,我将它们存储在基数 class:
中
export class ComponentBase {
protected unSubscriber$: Subject<any> = new Subject();
protected endWhenDestroyed = takeUntil(this.unSubscriber$);
protected filterOutNulls = filter(x => notNullOrUndefined(x));
ngOnDestroy() {
this.unSubscriber$.next();
this.unSubscriber$.complete();
}
...
稍后,其他组件继承上述 class 并简单地重用这些运算符:
class SomeClass extends ComponentBase {
...
someObservable$
.pipe(this.filterOutNulls, this.endWhenDestroyed)
.subscribe((y) => ...) // type of `y` is lost by typescript
...
如果我像平时那样使用运算符
class SomeClass extends ComponentBase {
...
someObservable$
.pipe(filter(x => !!x), takeUntil(this.unSubscriber$))
.subscribe((y) => ...)
...
然后,TypeScript 理解 y
的类型(在订阅上)是来自源可观察的类型。但是,当我使用我的 cached 运算符时,类型丢失了,我需要做 .subscribe((y: WhatEverType) => ...
才能编译和编辑器(IntelliJ,在我的例子中)停止抱怨.
现在,下面的代码使一切正常...
const getOp = <T>(): MonoTypeOperatorFunction<T> => {
return filter(x => !!x);
};
...
someObservable$
.pipe(getOp<TheType>())
.subscribe((y) => ...)
但是,我的问题是,是否有一种方法可以让类型继续像声明内联运算符函数时那样流动,而不必在订阅者或缓存运算符中手动转换类型,如上所示。
无论如何,如果有任何其他优雅的替代方法,我将不胜感激。
非常感谢
我没有意识到,通过使用我在问题末尾发布的确切解决方案,即使没有在使用 "cached" 运算符函数时手动转换类型,它也能正常工作。
所以,而不是像最初发布的那样:
const myFilter = filter(x => !!x);
const getOp = <T>(): MonoTypeOperatorFunction<T> => {
return myFilter;
};
someObservable$
.pipe(getOp<TheType>())
.subscribe((y) => ...)
做就够了
someObservable$
.pipe(getOp()) // no need to specify <TheType> here
.subscribe((y) => ...)
而且字体流畅 :)
(仅供参考。这是一个 Angular 5 应用程序,但这种情况本身并不是 Angular 所特有的)
我有几个运算符在不同的地方以相同的方式大量使用。为了减少重复代码,我将它们存储在基数 class:
中export class ComponentBase {
protected unSubscriber$: Subject<any> = new Subject();
protected endWhenDestroyed = takeUntil(this.unSubscriber$);
protected filterOutNulls = filter(x => notNullOrUndefined(x));
ngOnDestroy() {
this.unSubscriber$.next();
this.unSubscriber$.complete();
}
...
稍后,其他组件继承上述 class 并简单地重用这些运算符:
class SomeClass extends ComponentBase {
...
someObservable$
.pipe(this.filterOutNulls, this.endWhenDestroyed)
.subscribe((y) => ...) // type of `y` is lost by typescript
...
如果我像平时那样使用运算符
class SomeClass extends ComponentBase {
...
someObservable$
.pipe(filter(x => !!x), takeUntil(this.unSubscriber$))
.subscribe((y) => ...)
...
然后,TypeScript 理解 y
的类型(在订阅上)是来自源可观察的类型。但是,当我使用我的 cached 运算符时,类型丢失了,我需要做 .subscribe((y: WhatEverType) => ...
才能编译和编辑器(IntelliJ,在我的例子中)停止抱怨.
现在,下面的代码使一切正常...
const getOp = <T>(): MonoTypeOperatorFunction<T> => {
return filter(x => !!x);
};
...
someObservable$
.pipe(getOp<TheType>())
.subscribe((y) => ...)
但是,我的问题是,是否有一种方法可以让类型继续像声明内联运算符函数时那样流动,而不必在订阅者或缓存运算符中手动转换类型,如上所示。
无论如何,如果有任何其他优雅的替代方法,我将不胜感激。
非常感谢
我没有意识到,通过使用我在问题末尾发布的确切解决方案,即使没有在使用 "cached" 运算符函数时手动转换类型,它也能正常工作。
所以,而不是像最初发布的那样:
const myFilter = filter(x => !!x);
const getOp = <T>(): MonoTypeOperatorFunction<T> => {
return myFilter;
};
someObservable$
.pipe(getOp<TheType>())
.subscribe((y) => ...)
做就够了
someObservable$
.pipe(getOp()) // no need to specify <TheType> here
.subscribe((y) => ...)
而且字体流畅 :)