How can I extend RxJS?

91 Views Asked by At

I'm looking for a way to execute a callback whenever someone calls subscribe on an instance of a given class implementing Observable.

In the absence of a hook in the RxJS library, in pretty much any other object oriented language, I would:

  • inherit the class I want to customize (ReplaySubject in this case);
  • overwrite the subscribe method; and
  • execute my callback and then delegate the call to the superclass' subscribe method.

Something like this:

export class CallbackReplaySubject<T> extends ReplaySubject<T> {

  subscribe(observer: Partial<Observer<T>>): Unsubscribable {
    this.triggerCallback();
    return super.subscribe(observer);
  }

  private triggerCallback(): void {
    // do something when someone subscribes
  }
}

In RxJS v7 using TypeScript I'm getting this error message:

Property 'subscribe' in type 'CallbackReplaySubject<T>' is not assignable to the same property in base type 'ReplaySubject<T>'.
  Type '(observer: Partial<Observer<T>>) => Unsubscribable' is not assignable to type '{ (observerOrNext?: Partial<Observer<T>> | ((value: T) => void) | undefined): Subscription; (next?: ((value: T) => void) | null | undefined, error?: ((error: any) => void) | ... 1 more ... | undefined, complete?: (() => void) | ... 1 more ... | undefined): Subscription; }'.
    Type 'Unsubscribable' is missing the following properties from type 'Subscription': closed, _parentage, _finalizers, add, and 4 more.

The deeper I dig into this, the more I come into contact with "underscored" RxJS methods marked as internal, yelling "KEEP OFF!" at me, preventing any customization whatsoever.

So instead of inheritance, I tried the delegation pattern. Well that won't work either because Observable isn't an interface but a class. So I end up entangled with these "underscored" internal methods and members again.

Can anybody show me a way out of this?

Up to and including RxJS v6, I was able to solve this with inheritance, inheriting ReplaySubject's internal _subscribe method.

0

There are 0 best solutions below