What is the proper way to specify the type for the iterable response of Promise.all()?

It's common knowledge that Promise.all will return settled promises in the same order of the requested iterable.

I'm currently grappling with how to correctly define types for individual settled resolves. I am utilizing Axios for handling asynchronous calls.

Promise.all([
   <void, A>call an API a with response type A,
   <void, B>call another API b with response type B,
   <void, C>call another API c with response type C
]).then(([
       Response aa of type A: ?,
       Response bb of type B: ?,
       Response cc of type C: ?
   ]) => {
});

All responses are of type AxiosResponse<A | B | C>. However, explicitly setting it to this may cause problems when trying to access a property that doesn't exist in all response types, leading to errors like bb.test.

Is it possible to specify the type of each individual response like this?

]).then(([
       Response aa of type A: AxiosResponse<A>,
       Response bb of type B: AxiosResponse<B>,
       Response cc of type C: AxiosResponse<C>
   ]) => {

Note: The compiler is handling the types implicitly as well.

Answer №1

If you define the array as a literal, as seen in your question, it will function properly. Bergi's observation in the comments highlights that Promise.all is indicated to accept a tuple type.

declare var a: Promise<A>;
declare var b: Promise<B>;
declare var c: Promise<C>;

Promise.all([a, b, c]).then(([a1, b1, c1]) => {
  (a1);
  //^? (parameter) a1: A
  (b1);
  //^? (parameter) b1: B
  (c1);
  //^? (parameter) c1: C
});

Nevertheless, TypeScript will assume that when an array is declared, it will attempt to identify a "best common type" that aligns with all elements of the array. This can hinder your ability to destructure the array into specific types.

let array = [a, b, c];
//  ^? let array: (Promise<A> | Promise<B> | Promise<C>)[]

Promise.all(array).then(([a1, b1, c1]) => {
  (a1);
  //^? (parameter) a1: (A | B | C)
  (b1);
  //^? (parameter) b1: (A | B | C)
  (c1);
  //^? (parameter) c1: (A | B | C)
});

To maintain the types but still utilize an array, you must incorporate the const assertion as const to direct TypeScript to treat it as a tuple, similar to what was done in the initial example.

let tuple = [a, b, c] as const;
//  ^? let tuple: readonly [Promise<A>, Promise<B>, Promise<C>]

Promise.all(tuple).then(([a1, b1, c1]) => {
  (a1);
  //^? (parameter) a1: A
  (b1);
  //^? (parameter) b1: B
  (c1);
  //^? (parameter) c1: C
});

Refer to the TypeScript playground for the given examples.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for displaying script commands within package.json files?

With a multitude of repositories, each one unique in its setup, I find myself constantly referencing the package.json file to double-check the scripts. "scripts": { "start": "npm run dev" "build:dev": "N ...

Sporadic UnhandledPromiseRejectionWarning surfacing while utilizing sinon

Upon inspection, it appears that the objects failApiClient and explicitFailApiClient should be of the same type. When logging them, they seem to have identical outputs: console.log(failApiClient) // { getObjects: [Function: getObjects] } console.log(expli ...

Difficulty with retrieving and displaying extensive datasets in Vue/Nuxt leading to reduced speed

My current challenge involves rendering a list in Vue based on data fetched via Axios. The items have unique IDs, codes (strings), and descriptions, with over 14,000 of them stored in the system's MySQL database. These items are categorized into 119 c ...

Is it possible to compile using Angular sources while in Ivy's partial compilation mode?

Error: NG3001 Unsupported private class ObjectsComponent. The class is visible to consumers via MasterLibraryLibModule -> ObjectsComponent, but is not exported from the top-level library entrypoint. 11 export class ObjectsComponent implements OnInit { ...

How to update an Angular 2 component using a shared service

My question is regarding updating components in Angular 4. The layout of my page is as follows: Product Component Product Filter Component Product List Component I am looking to link the Product Filter and Product List components so that when a user c ...

Unraveling the complexities of Typescript's Advanced Type NonFunctionPropertyNames

Delving deeper into the realm of advanced types in Typescript, I came across an intriguing type called NonFunctionPropertyNames. This type is designed to extract only the properties of a given object that are not functions. type NonFunctionPropertyNames&l ...

`The Importance of Validating Enum Arrays in Typescript Using Class-Validator`

Is there a way to validate an array of enums in a DTO without getting misleading error messages? Here is an example of my DTO: import { IsArray, IsEmail, IsEnum, IsIn, IsNotEmpty, IsString } from "class-validator"; import { UserAction, UserModul ...

Tips on how to retrieve an Observable Array instead of a subscription?

Is there a way to modify this forkJoin function so that it returns an observable array instead of a subscription? connect(): Observable<any[]> { this.userId = this.authService.userId; this.habits$ = this.habitService.fetchAllById(this.userId); this.s ...

Set up a unique database in memory for every individual test

Is it feasible to create an in-memory database for each test scenario? My current approach involves using the code snippet below, which functions properly when running one test file or utilizing the --run-in-band option. import _useDb from "@/useDb&q ...

Issue with importing Typescript and Jquery - $ function not recognized

Currently, I am utilizing TypeScript along with jQuery in my project, however, I keep encountering the following error: Uncaught TypeError: $ is not a function Has anyone come across this issue before? The process involves compiling TypeScript to ES20 ...

Tips for specifying the return type of app.mount()

Can I specify the return value type of app.mount()? I have a component and I want to create Multiple application instances. However, when I try to use the return value of mount() to update variables associated with the component, TypeScript shows an error ...

"Error: The React TypeScript variable has been declared but remains

Seeking guidance on ReactTS. I'm puzzled by the undefined value of the variable content. Could someone shed light on why this is happening and how to assign a value to it for passing to <App />? The issue persists in both the index.tsx file and ...

Access network path through browser using Angular

I'm having trouble opening a network path from my browser using the code below. The browser keeps throwing an error saying it's unable to load local resources. Can you please provide some advice on this issue? public openUrl() { window.o ...

The custom component is not updating the NgIf directive in HTML even though it receives a boolean variable

I am struggling with a custom component that includes an *ngIf in its view to handle a boolean variable, but for some reason the *ngIf directive is not working. Here is the code snippet: Component @Input('title') titleText; @Input('backButt ...

Testing Angular HTTP error handlers: A comprehensive guide

Below, you will find an example of code snippet: this.paymentTypesService.updatePaymentTypesOrder('cashout', newOrder).subscribe(() => { this.notificationsService.success( 'Success!', `Order change saved successfully`, ...

Sharing code between a node.js server and browser with Typescript: A step-by-step guide

I have an exciting project in mind to develop a multiplayer javascript game using a node.js server (with socket.io) and I am looking for a way to share code, specifically classes, between the web client and the server. Luckily, I came across this resource: ...

Challenges with importing and using jspdf and autotable-jspdf in Angular 8

Issue with Generating PDF Using Angular 8, JSPDF, and JSPDF-AutoTable I am facing a challenge with exporting/generating a PDF based on an HTML grid. I need to make some DOM changes with CSS, remove toggle buttons, alter the header, etc. However, all the s ...

Capture all HTTP requests made by Angular2

I'm trying to find a way to intercept and modify all HTTP requests made by Angular by adding custom headers. In previous releases prior to angular2 RC5, this was achieved by extending the BaseRequestOptions like this: class MyOptions extends BaseRequ ...

Preventing CORS Block with Vuex and Axios to Access-control-allow-origin

Here is the issue: https://i.sstatic.net/QzRT7.png To address this error, I ensured that my backend API includes the acess-control-allow-origin header: https://i.sstatic.net/8wfTu.png Below is the snippet of my code utilizing axios: loadTopSales ...

Angular integration problem with aws-amplify when signing up with Google account

I am attempting to integrate AWS-Amplify(^4.3.0) with angular-12 and typescript (4.3.5). I have followed the documentation to configure amplify properly, but when trying to start the app, I encountered some amplify errors as shown below. Warning: D:\G ...