Hussain Ali Akbar
Hussain Ali Akbar

Reputation: 1655

How to preserve Typescript return types when calling Promise.all?

I have the following code where i have two functions which return objects of two different types (InterfaceA and InterfaceB)

Now, when i call Promise.all on them, i cant define the type of promises variable so i have to go with any.

  interface InterfaceA {
    value: string;
  }

  interface InterfaceB {
    value: number;
  }

  const returnA = (): Promise<InterfaceA> => {
    const obj: InterfaceA = {
      value: 'a'
    };
    return Promise.resolve(obj);
  };

  const returnB = (): Promise<InterfaceB> => {
    const obj: InterfaceB = {
      value: 1
    };
    return Promise.resolve(obj);
  };

  const promises: any = [returnA(), returnB()];
  const res = await Promise.all(promises);

  console.log(res)
  const objA: InterfaceA = res[0];

The problem is that once i get the response of Promise.all, and try to define the types of the responses, i get the following errors:

Type '{}' is not assignable to type 'InterfaceA'.
  Property 'value' is missing in type '{}'. (2322)
Type '{}' is not assignable to type 'InterfaceA'. (2322)

I am not exactly sure how to deal with this and what i can do to preserve the type of the objects that i get in the response of Promise.all?

Thanks!

Upvotes: 5

Views: 6167

Answers (2)

Estus Flask
Estus Flask

Reputation: 222319

The problem is that promises type isn't precisely inferred as (Promise<InterfaceA> | Promise<InterfaceB>)[].

It can be properly typed with tuple type:

  const promises: [Promise<InterfaceA>, Promise<InterfaceB>] = [returnA(), returnB()];
  const res = await Promise.all(promises);

This problem can be avoided by eliminating promises temporary variable:

  const res = await Promise.all([returnA(), returnB()]);

Upvotes: 12

Paulquappe
Paulquappe

Reputation: 144

I didnt fully understand you intention, what i understood is that you wanted to achive something like this with the as operator.

const returnA = (): Promise<InterfaceA> => {
    const obj: InterfaceA = {
      value: 'a'
    };
    return Promise.resolve(obj as InterfaceA);
  };

Upvotes: 0

Related Questions