Reputation: 16236
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:
filter
, could only be used on pipe
method?pipe
only receives one?Upvotes: 4
Views: 3093
Reputation: 28434
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:
pipe(...fn: OperatorFunction<X,Y>)
by defining this interface as an extension of OperatorFunction
Upvotes: 4