const of = require('rxjs').of;
const map = require('rxjs/operators').map
of(123).pipe(
map(num => num.toString()),
map(str => str.substring(0,1)),
).subscribe(console.log);
In the second map above, the type of str parameter is correctly inferred from the previous map that returns a string. I am curious how typescript is inferring the type in the second map operator.
Is this RxJS who nicely designed the code so that it can happen?
Or is it just VS code that has special IntelliSense for RxJS?
I'd say it is all handled by RxJS.
Looking at the pipe overloads
pipe(): Observable<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>;
...
we can see that there's a lot going on.
OperatorFunction<T, A> type refers to a function whose single parameter is an Observable of type T and whose return type is also an Observable of type A:
export interface OperatorFunction<T, R> extends UnaryFunction<Observable<T>, Observable<R>> {}
Let's also have a look at map's signature
export function map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R> { ... }
As you can see, its return type will be a function that receives an observable and returns another observable. In this case, the type of the returned Observable(R) is inferred from the provided projection function: (value: T, index: number) => R
So, if you have
const src$ = of(1).pipe(map(v => '' + v));
src$ will be an observable whose type T will be string.
And here's why type inference also works inside subscribe:
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription; // Providing callbacks
subscribe(observer?: PartialObserver<T>): Subscription; // Providing an observer object
where T is the inferred type of the Observable(i.e from map's provided fn in this case).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With