I'm trying to understand the pipe operator of observable API:

 export declare class Observable<T> implements Subscribable<T> { ....... pipe<A>(op1: OperatorFunction<T, A>): Observable<A>; pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>; pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>; pipe<A, B, C, D>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>): Observable<D>; pipe<A, B, C, D, E>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>): Observable<E>; pipe<A, B, C, D, E, F>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>): Observable<F>; pipe<A, B, C, D, E, F, G>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>): Observable<G>; pipe<A, B, C, D, E, F, G, H>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>): Observable<H>; pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>): Observable<I>; ....... } 

As you could see, all of pipe overload methods receive and OperationFunction type.

Lets check the filter operator API:

export declare function filter<T, S extends T>(predicate: (value: T, index: number) => value is S, thisArg?: any): OperatorFunction<T, S>; export declare function filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>; 

As you can see, you have an overload method that returns an OperationFunction and another that returns MonoTypeOperatorFunction.

I have the following questions:

  • RxJS6 operators like filter, could only be used on pipe method?
  • Why in filter we have a overload method that return different types but the pipe only receives one?

1 Answer

RxJS6 operators like filter, could only be used on pipe method?

Pipe methods are pure high-order functions. So no, they can be used as any other method. The difference being, that if you invoke them outside of a pipe closure, you will lose type intellisense.

Why in filter we have a overload method that return different types but the pipe only receives one?

Take the following with a grain of salt

Most operators/use cases in streams involve a transformation, eg transforming a value x from a domain X to a value y from a domain Y. This concept is abstracted by the definition of the OperatorFunction<X,Y> interface.

In the case of the filter operator, we have a specialized case of OperatorFunction<X,Y>, in which the condition X is Y and Y is X is fulfilled, as the operation takes a value x from the domain X and transforms it into a value y from the same domain X. This special case is once again abstracted by the MonoTypeOperatorFunction<X> interface, which is indeed defined as an extension of OperatorFunction<X,X>.

My guess is that the MonoTypeOperatorFunction interface was created with 2 goals:

  • Abstract the previously explained concept by defining a explicit interface
  • Keep the contract of pipe(...fn: OperatorFunction<X,Y>) by defining this interface as an extension of OperatorFunction

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.