Typescript typing error with forkJoin
Asked Answered
P

2

3

I'm experiencing a TypeScript type check failure when using the forkJoin operator form RxJS. This is the code in question:

let products = this.http.get(productUrl, { headers: this.headers })
            .map(response => response.json().data as Product[]);
        let loans = Observable.of(loan);

        return Observable.forkJoin([products, loans])
            .map(data => {
                let resultProducts = data[0] as Product[];
                if (resultProducts.length > 0) {
                    lead.Product = resultProducts.find(i => i.ID == productId);
            }
            lead.Loan = data[1];
            return lead;
        });

The error tsc is emitting is:

 Type 'Loan' cannot be converted to type 'Product[]'.

My understanding of forkJoin is that data[0] should be a Product[] and data[1] should be a Loan, but tsc seems to disagree. Is my understanding incorrect? Am I missing some typing that would tell tsc hat I want?

Pinniped answered 17/8, 2017 at 15:9 Comment(1)
lead.Loan = data[1]; return lead; is out of .map and Observable returns already, but I may be misguidedNewsletter
C
2

Try using Observable.forkJoin without passing in an array.

// forkJoin with array
return Observable.forkJoin([products, loans])
// forkJoin without array
return Observable.forkJoin(products, loans)
  .map(data => {
    let resultProducts = data[0] as Product[];
    // ...
    lead.Loan = data[1];
  })
Census answered 17/8, 2017 at 19:32 Comment(0)
H
1

There are numerous signature overloads for forkJoin.

When you call forkJoin, passing an array:

Observable.forkJoin([products, loans])

The signature that's matched is this one:

static create<T>(
  sources: SubscribableOrPromise<T>[]
): Observable<T[]>;

Note that there is only a single type variable (T), so all of the array elements are inferred to be a single type. And T will be Product[] | Loan, which is why the error you mentioned is effected. (You cannot assert that something that could potentially be a Loan is a Product[].)

If you specify separate arguments instead:

Observable.forkJoin(products, loans)

It will match this signature:

static create<T, T2>(
  v1: SubscribableOrPromise<T>,
  v2: SubscribableOrPromise<T2>
): Observable<[T, T2]>;

And the emitted value will have a tuple type [Product[], Loan] and the error won't be effected, as TypeScript will know that data[0] is a Product[].

Handout answered 18/8, 2017 at 0:42 Comment(1)
There is a limit though of 6 for the second signature type.Adrial

© 2022 - 2024 — McMap. All rights reserved.