I come across this often in Angular when I work with combineLatest
to combine 2 observables that emit optional values.
The basic pattern is this:
const ob1: Observable<Transaction[] | null>;
const ob2: Observable<Price[] | null>;
const currentValue = combineLatest([ob1, ob2]).pipe(
filter(([a, b]) => !!a && !!b),
map(([a, b]) => {
// Here the type of both and a and b is nullable
const x = a.map(a => a.id); // This gives compilation error that a can be null
});
I want to do work in the map
function to combine the events once both observables emit non null values.
The filter
does indeed filter but the type of each element is still T | null
.
I want the type to be Transaction[]
for a
and Price[]
for b
without using a!
or b!
.
This pattern repeats a lot in my code and I would like to find a solution that is short and elegant.
I found some answers how to fix this for a single value. But how do I do this for a tuple or array?
CodePudding user response:
How about simple casting? Add another map
to pipe after filter
: map(([a,b])=> [a,b] as [Transaction[], Price[]]),
or even cast it inside your map
body.
CodePudding user response:
Creating two types of your required tupple will help you to solve your problem.
type V = [Transaction[] | null, Price[] | null];
type R = [Transaction[], Price[]];
const ob1: Observable<Transaction[] | null>;
const ob2: Observable<Price[] | null>;
const currentValue = combineLatest([ob1, ob2]).pipe(
filter(([a, b]: V)=> !!a && !!b) as OperatorFunction<V, R>,
map(([a, b]: R) => {
const x = a.map(a => a);
const y = b;
return x;
})).subscribe((r) => console.log( r));