TypeScript's reusable retry functionality

This specialized function takes an input function as its first argument and a set of customizable options as its second. It repeatedly calls the provided function, retrying until either a successful result is returned or the maximum number of attempts is reached. Any outcome from the function, whether it returns a value or throws an error, is made accessible to external users.

The challenge at hand:

I'm tasked with typing this function in such a way that any parameter-less function can be retried without encountering type errors in the index.ts file. The original return type of the input function must remain intact, enclosed within a promise structure.

function wait(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export async function retryFn(fn, { tries, interval }) {
  try {
    return fn();
  } catch (e) {
    const newTries = tries - 1;

    if (newTries === 0) {
      throw e;
    }

    await wait(interval);

    return retryFn(fn, { tries: newTries, interval });
  }
}

Answer №1

const FuncNoParams = () => any;
const Settings = { attempts: number, duration: number};

export async function retryFunction<T extends FuncNoParams>(
    func: T,
    { attempts, duration }: Settings
) : Promise<ReturnType<T>>
{
    //...
}

This specific function type guarantees that only functions with arguments of type () => any can be used. In this context, () => any refers to a function that takes no parameters and returns an any value.

The utility type ReturnType allows us to extract the return type from this generic function type.

Answer №2

One effective approach is to utilize the RxJs retry operator, which allows you to specify the number of attempts you wish to make before giving up. By encapsulating the result value in an observable instead of a Promise, this method can offer a more reliable solution.

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

Saving an array to a text file with a new line delimiter can easily be achieved using Types

I have an array of plain strings that I need to save to a text file. However, I'm encountering an issue where the strings are being saved as comma separated values instead of new lines. Here is the data I currently have: https://i.sstatic.net/r3XVr.j ...

What is the process to enable mandatory validation after a change in input in Angular 4?

Currently, I am working on a project using Angular 4. One of the tasks I need to achieve is validation. <input [(ngModel)]="someModel" required placeholder="some placeholder"/> The validation triggers immediately, but I want it to only trigger aft ...

Issue with Angular 6 Share module functionality not functioning as expected

While creating my Angular 6 application, I encountered an issue with sharing a header across multiple pages. I tried including it but it doesn't seem to be working. Can anyone point out what I might be doing wrong? For a demonstration, you can visit . ...

Tips for implementing pagination on a large JSON file without traditional pagination controls

Looking for the best way to implement pagination in a NextJs app that loads products from a local JSON file? This JSON file doesn't have any page properties, so the only option is to limit the number of products shown by using slice: {Object ...

Confounding Typescript Type Bindings

I am facing an issue with my Typescript component that uses react-jss and the classes object for styling. The error message I'm getting is: Binding element 'classes' implicitly has an 'any' type., and I'm struggling to find a ...

An unexpected issue occurred while attempting to create a new Angular app using the command ng

Currently in the process of deploying my angular application and utilizing Infragistics. Following their Documentation, I used npm install Infragistics for installation. However, when I run ng new --collection="@igniteui/angular-schematics" I e ...

Can TypeScript provide a method for verifying infinite levels of nested arrays within a type?

Check out this example The concept behind this is having a type that can either be a single object or an array of objects. type SingleOrArray<T> = T | T[]; The structure in question looks like this: const area: ItemArea = [ { name: 'test1& ...

Ensure that data is properly filtered before being presented in the Angular 5 component

Currently, I am dealing with football data retrieved from an API. https://i.sstatic.net/MRSsH.jpg When I make a request to this API endpoint, all the available lists are displayed. My goal is to organize the list based on the game status, such as Finishe ...

Add inline CSS to the <html> element using TypeScript when clicked on

My experience with TypeScript is still new, and I recently found myself confused when trying to apply inline CSS to a tag on click. I initially thought it would be simple, but in TypeScript, things seem to work differently. I attempted to use document.quer ...

Undefined values do not function properly with discriminated unions

In my React component, there are two props named required and fallback. The type definition for these props is as follows: type Props = | { required? : true | undefined, fallback : React.ReactNode } | { required? : false, fallback? : React.Rea ...

Develop Connective Plugins using Angular 12

I am working on implementing a new feature for my app that involves storing certain modules on the backend and loading them dynamically based on user demand. Instead of loading all modules at once, I want to only load the necessary modules just before the ...

Angular 2's ng-required directive is used to specify that

I have created a model-driven form in Angular 2, and I need one of the input fields to only show up if a specific checkbox is unchecked. I was able to achieve this using *ngIf directive. Now, my question is how can I make that input field required only whe ...

What is the process of using observables in Angular to retrieve a number or variable?

While working on an angular service that calls an API and processes a large amount of data, I encountered an issue. I was trying to count the occurrences of each type in the data and send back that count along with the data itself. However, I found that wh ...

The TypeScript autocomplete feature is displaying two cars when I only need one

I am currently working with two props, one named car and the other named allStations. Whenever I press car, I am getting car.car as autocomplete, but I only want something like car.id, not car.car.id. Could someone please help me figure out what I am doi ...

Changing Observable to Promise in Angular 2

Q) What is the best way to convert an observable into a promise for easy handling with .then(...)? The code snippet below showcases my current method that I am looking to transform into a promise: this._APIService.getAssetTypes().subscribe( assetty ...

When it comes to providedIn in Angular, which of 'root', 'platform', or 'any' is the preferred choice for different scenarios?

When it comes to providedIn in Angular, which option out of 'root', 'platform', 'any' should be the preferred choice in different cases? https://angular.io/api/core/Injectable 'root' : The application-level injec ...

Exporting an angular component as a module

I have successfully created a widget using Angular elements that works well in HTML. However, I am unsure of how to export it as a module for use in other Angular, React, Vue web applications. I want to be able to import import { acmaModule } from package- ...

Tips for effectively typing a collection of React wrappers in TypeScript

I encountered a situation in my team's application where we need the ability to dynamically compose component wrappers (HOCs) without prior knowledge of all the wrapper interfaces. This is mostly needed for swapping out context providers when renderin ...

An error occurs when attempting to access a property that does not exist on type 'never'. Why is this considered an error rather than a warning?

I am experiencing an issue with the following code snippet: let count: number | undefined | null = 10; count = null; let result: string | undefined | null = count?.toFixed(2); console.log(`Result: ${result}`); The error message I received is as follows: ...

Advantages of incorporating types through imports versus relying solely on declaration files in Typescript

We are currently in the process of switching from plain JavaScript to TypeScript. One aspect that I personally find frustrating is the need to import types. In my opinion, importing types serves no real purpose other than cluttering up the import section ...