In the process of setting up an NgRx store, I came across a pattern that I found myself using frequently:
concatMap(action => of(action).pipe(
withLatestFrom(this.store.pipe(select(fromBooks.getCollectionBookIds)))
)),
(found at the bottom of )
To avoid clutter in my code, I wanted to create a utility operator to streamline this pattern.
After some thought, I devised an implementation that should do the job:
export function concatMapLatestFrom<A extends Action>(
...xs: Array<ObservableInput<never>>
): OperatorFunction<A, unknown> {
return function (source: Observable<A>): Observable<unknown> {
return source.pipe(
concatMap((action) => of(action).pipe(withLatestFrom(...xs))),
);
};
}
I also added some properly typed overloads:
export function concatMapLatestFrom<X1, A extends Action>(
source1: ObservableInput<X1>,
): { (source1: X1): OperatorFunction<A, [A, X1]> };
export function concatMapLatestFrom<X1, X2, A extends Action>(
source1: ObservableInput<X1>,
source2: ObservableInput<X2>,
): { (source1: X1, source2: X2): OperatorFunction<A, [A, X1, X2]> };
export function concatMapLatestFrom<X1, X2, X3, A extends Action>(
source1: ObservableInput<X1>,
source2: ObservableInput<X2>,
source3: ObservableInput<X3>,
): {
(source1: X1, source2: X2, source3: X3): OperatorFunction<
A,
[A, X1, X2, X3]
>;
};
However, I encountered issues where the compiler deemed the overload signature incompatible with the implementation. Even though I commented out one, the same issue arose with the next one in line.
The reason behind this discrepancy eludes me, and unfortunately, the compiler does not provide detailed explanations for these inconsistencies.