如何在不破坏 TypeScript 的类型检查的情况下"cache" rxjs 可排序运算符并在多个".pipe()"调用中重用它们



(仅供参考。它的上下文是一个 Angular 5 应用程序,但是这种情况并不是 Angular 本身所特有的)

我有一些运算符在不同的地方以相同的方式使用很多。为了减少代码重复,我将它们存储在基类中:

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 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的类型(在订阅上)是来自源可观察对象的类型。但是,当我使用缓存的运算符时,类型会丢失,我需要执行.subscribe((y: WhatEverType) => ...才能编译它,并且编辑器(在我的例子中为 IntelliJ)停止抱怨。

现在,下面的这段代码使一切正常...

const getOp = <T>(): MonoTypeOperatorFunction<T> => {
return filter(x => !!x);
};
...
someObservable$
.pipe(getOp<TheType>())
.subscribe((y) => ...)

但是,我的问题是,是否有一种方法可以让类型继续流动,就像在内联声明运算符函数时一样,而不必在订阅服务器或缓存运算符中手动转换类型,如上所示。

无论如何,我会欣赏任何其他优雅的替代方案。

确实谢谢

我没有意识到,通过使用我在问题末尾发布的确切解决方案,即使不手动将类型转换为"缓存"运算符函数的使用,它也能正常工作。

因此,而不是按照最初发布的方式执行:

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) => ...)

而且类型流:)

最新更新