Creating an asynchronous function that can handle a variable number of arguments and returns the appropriate data type

I'm looking to create a helper function that can wrap an existing async function with a variable number of arguments, allowing me to call it like this:

const submit = wrapLoading(async (values: string[]) {
  // await something with values
  return true
})

submit(['1', '2'])  // Call it

However, I've run into an issue where the return type is always Promise<any>, even though in the example above, the function being wrapped returns a Promise<boolean>. Here's my implementation. Can anyone help me understand why this is happening?

export const wrapLoading = <F extends(...args: any[]) => Promise<any>>(
  process: F
) => async (...args: Parameters<F>) => {
  isLoading.value = true
  const result = await process(...args)
  isLoading.value = false
  return result
}

I've tried using another argument to specify the return type, but then it always returns a Promise<unknown>. I'm struggling to find an elegant solution to this problem. Any assistance would be greatly appreciated!

Answer №1

To determine the data type, you can utilize the utility types ReturnType and Awaited!

let loadingStatus: {value: boolean};

export const handleLoading = <F extends (...args: any[]) => Promise<any>>(
  execute: F
) => async (...args: Parameters<F>): Promise<Awaited<ReturnType<F>>> => {
  loadingStatus.value = true;
  const outcome = await execute(...args);
  loadingStatus.value = false;
  return outcome;
}

const processRequest = handleLoading(async (dataValues: string[]) => {
  // perform some task with the provided values
  return true;
})

const resultOfExecution = processRequest(['1', '2'])  // Trigger the function call
    //^?  Promise<boolean>

Playground

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

Pattern matching to eliminate line breaks and tabs

Hey there, I'm working with a string: "BALCONI \n\n\t\t\t\t10-pack MixMax chocolade cakejes" and trying to tidy it up by removing unnecessary tabs and new lines. I attempted using .replace(/(\n\t)/g, '&apo ...

Personalized ornamentation using TypeScript

Is there a way to access the variables of the class when using a decorator? @ExampleDecorator() export class UserController { private userData: string = "example"; } export const ExampleDecorator = (config: IConfigSettings) => (target: Object) =&g ...

Bring in a collection of classes of various types from one TypeScript file to another

In my code file exampleA.ts, I define an object as follows: import { ExampleClass } from 'example.ts'; export const dynamicImportations = { ExampleClass }; Later, in another file named exampleB.ts, I import an array that includes class types and ...

What is the best way to leverage TypeScript for destructuring from a sophisticated type structure?

Let's consider a scenario where I have a React functional component that I want to implement using props that are destructured for consistency with other components. The component in question is a checkbox that serves two roles based on the amount of ...

I have to create a duplicate for the clipboard containing a dynamic variable in Angular

CSS Note: The Technical.url variable in the specification is constantly changing, and every time I click the button, I want to copy the URL. <div fxLayout="column" fxLayoutAlign="center start" fxFlex="70" class="" ...

It is possible that req.user may be undefined, especially when using express and passport.js

I am facing an issue with my Node.js TypeScript authentication system that utilizes passport. The problem arises when I attempt to access req.user in a specific route, resulting in the error message: Object is possibly 'undefined'. This behavio ...

Challenges encountered when unit testing ngx-translate

0 I am encountering issues with unit testing while using the ngx-translate library. Despite adding a provider for TranslateService, the tests keep asking for more providers, creating an endless loop of dependencies. Specifically, I am trying to unit test ...

Creating intricate structures using TypeScript recursively

When working with Angular and TypeScript, we have the power of generics and Compile-goodness to ensure type-safety. However, when using services like HTTP-Service, we only receive parsed JSON instead of specific objects. Below are some generic methods that ...

Angular: Navigating to a distinct page based on an API response

In order to determine which page to go to, based on the response from an API endpoint, I need to implement a logic. The current API response includes an integer (id) and a string (name). Example Response: int: id name: string After making the API call, I ...

Utilize a combination of generic parameters as the keys for objects in TypeScript

Is there a method to utilize multiple generic parameters as object keys in TypeScript? I came across this answer which works well when there is only one parameter, but encounters issues with more than one. The error message "A mapped type may not declar ...

Getting node siblings within an Angular Material nested tree: A comprehensive guide

Struggling to retrieve the list of sibling nodes for a specific Angular Material tree node within a nested tree structure. After exploring the Angular Material official documentation, particularly experimenting with the "Tree with nested nodes," I found t ...

The module 'DynamicTestModule' experienced an import of an unexpected value under the name 'SohoComponentsModule'

I have been working on an angular 2 application using our UI team's library. The progress has been smooth, thanks to the easy integration of their components through import statements in my app.module.ts: import { BrowserModule } from '@angular/ ...

Access data inside nested objects with specified data type

Imagine the code snippet below: type Parent = { children: Child[] } type Child = { label: string } const parent: Parent = { children: [ { label: 'label1' }, { label: 'label2' } ] } How can I use generics to ...

Focusing on the active element in Typescript

I am working on a section marked with the class 'concert-landing-synopsis' and I need to add a class to a different element when this section comes into focus during scrolling. Despite exploring various solutions, the focused variable always seem ...

The functionality of ngModel seems to be malfunctioning when used within select options that are generated inside

I'm currently working on dynamically adding options to an HTML select element within a for loop. I am using [(ngModel)] to get the selected option, but initially no option is pre-selected. Here's a snippet of the code: <table align="center"& ...

"Extra loader required to manage output from these loaders." error encountered in React and Typescript

After successfully writing package 1 in Typescript and running mocha tests, I confidently pushed the code to a git provider. I then proceeded to pull the code via npm into package 2. However, when attempting to run React with Typescript on package 2, I enc ...

Issue with Angular: Child component not receiving data after successful parent component call

I'm currently working with a parent and child component setup. Within the child component, I have a button configured like this: //child.component.html <button mat-raised-button [disabled]="!form.valid || submitButtonDisable" type = 'Submi ...

Mocking Firestore v9 getDocs() in Jest: A Comprehensive Guide

After upgrading our webapp from Firebase v8 to v9, we encountered various issues due to the new syntax. As I am still relatively new to Jest and Firebase/Firestore, not everything is completely clear to me yet ... I am attempting to mock getDocs from fire ...

The Firebase Cloud Function is failing to trigger on the onCreate event within the Firebase Realtime Database

I recently deployed a function to Firebase with the following code: import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; console.log('FILE LOADED'); const serviceAccount = require(' ...

How can you update the property values of a CSS class that already exists in an Angular2+ controller?

In my styles.css file, I have a CSS class called '.users' with a property of color. Now, I am looking to dynamically change the color property value of the 'users' class based on certain conditions in my controller. For instance, I want ...