RxJS wrongly infers the type after using map operator with forkjoin
ernest-rudnicki opened this issue · 2 comments
Describe the bug
Hey there. I wonder if this is some limitation or Typescript or just a bug in RxJS
I am using forkJoin
that has two observables with arrays (itemsA
, itemsB
) that have different types. Then I am using a pipe
with map
to add additional item to itemsA
array and return both arrays as the tuple [itemsA, itemsB]
. After that I subscribe
to the forkJoined observable and try to assign one of the arrays to the new variable called allA
that has type explicitly set to ItemA[]
. However, TypeScripts shows the error, that it is not assignable, because both arrays in the tuple have now ItemA[] | ItemB[]
.
Type 'ItemA[] | ItemB[]' is not assignable to type 'ItemA[]'.
Type 'ItemB[]' is not assignable to type 'ItemA[]'.
Property 'propA' is missing in type 'ItemB' but required in type 'ItemA'.(
Expected behavior
The first item of the tuple should have the type ItemA[]
and the second item should haveItemB[]
.
Reproduction code
import { forkJoin, of, map } from 'rxjs';
interface ItemA {
propA: string;
}
interface ItemB {
propB: string;
}
const itemsA: ItemA[] = [{propA: 'asd'}, {propA: 'bcd'}]
const itemsB: ItemB[] = [{propB: 'asd'}, {propB: 'bcd'}]
let allA: ItemA[] = []
forkJoin([of(itemsA), of(itemsB)]).pipe(map(([a, b]) => {
a.push({propA: 'cdf'})
return [a, b]
})).subscribe(([a, b]) => {
allA = a // here is where the error happens
})
Reproduction URL
https://stackblitz.com/edit/typescript-nayvqr?file=index.ts
Version
7.8.1
Environment
No response
Additional context
No response
Not a RxJS issue, but it's how typescript works.
Typescript thinks your map is returing an Array<ItemA | ItemB>
. Sort like if you do return [1,2,3]
it will say that the function returns Array<number>
instead of [number, number, number]
.
You have to explicitely tell it it's a tuple type for this to work. Either const result: [ItemA, ItemB] = [a,b]; return result;
or return [a,b] as const
Thanks for help! Looks like it can be closed then