Search code examples
arraysmergerxjsobservableflatten

Why an Observable<Persons[]> can be used as mergeAll input?


According to the documentation :

mergeAll<O extends ObservableInput>(concurrent: number = Infinity): OperatorFunction<O, ObservedValueOf> Returns

OperatorFunction<O, ObservedValueOf>: A function that returns an Observable that emits values coming from all the inner Observables emitted by the source Observable.

If I am not mistaken this mean that the mergeAll method Flattens an Observable-of-Observables. So mergeAll takes an Observable-of-Observables as input.

https://rxjs.dev/api/operators/mergeAll

But, according to code sample :

personWithAddress$ = this.persons$.pipe(
    mergeAll(), // flatten to Observable<Person>
    
  );

If I am not mistaken, we have mergeAll<Persons[]>() where a Observable-of-Observables is expected.

persons$ = this.service.get(selectPersons);
         // ^? Observable<Persons[]> where Person = {id: number, name: string}

https://dev.to/this-is-angular/managing-array-of-observables-3alf


Solution

  • Well actually, the docs state that the signature is:

    mergeAll<O extends ObservableInput<any>>(concurrent: number = Infinity): OperatorFunction<O, ObservedValueOf<O>>;
    

    And ObservableInput is:

    type ObservableInput<T> = Observable<T> | InteropObservable<T> | AsyncIterable<T> | PromiseLike<T> | ArrayLike<T> | Iterable<T> | ReadableStreamLike<T>;
    

    And ObservedValueOf is:

    type ObservedValueOf<O> = O extends ObservableInput<infer T> ? T : never;
    

    And finally, OperatorFunction is:

    interface OperatorFunction<T, R> extends UnaryFunction<Observable<T>, Observable<R>> { /* [...] */ }
    

    Which makes Observable<T[]> a valid input as T[] satisfies ArrayLike<T> which in turn satifies ObservableInput<T>, and thus the input would be OperatorFunction<T[], T> which is simply a function of signature (arg: Observable<T[]>) => Observable<T>.