我如何 "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) => ...)

而且字体流畅 :)