Guide on implementing Typescript interface for JavaScript promises

As a newcomer to TypeScript, I am endeavoring to assign types to Promises in the code snippet below

Even though Promise<any> type has been specified for the promise variable, there are still error indications (squiggly red underlines) on .resolve, .reject, and .promise


const wrappedPromise = function() {
  var wrappedPromise = {},
    promise = new Promise(function(resolve, reject) {
      wrappedPromise.resolve = resolve;
      wrappedPromise.reject = reject;
    });
  wrappedPromise.then = promise.then.bind(promise);
  wrappedPromise.catch = promise.catch.bind(promise);
  wrappedPromise.promise = promise;
  return wrappedPromise;
};

Furthermore, I am pondering if the use of generics would be beneficial in this context. If so, how should they be applied?

Answer №1

Is it viable to incorporate generics in this scenario?

Absolutely, utilizing generics here is beneficial, especially when paired with an interface type for your encapsulated promise. While not mandatory, having the interface type will greatly simplify your implementation. Let's start by defining the interface:

interface WrappedPromise<T> extends Promise<T> {
    resolve(v: T): void;
    reject(e: Error): void;
    promise: Promise<T>;
}

You might need to make some adjustments based on your requirements. For instance, considering that a then handler could potentially transform the fulfillment into any type, using Promise<any> as the return type for then makes sense.

The next step involves assigning type arguments to your function and applying a Partial wrapper on wrappedPromise. This approach allows you to incrementally add properties that meet the criteria set forth by the WrappedPromise interface (finishing with a type assertion upon completion of all parts):

const wrappedPromise = function<T>(): WrappedPromise<T> {
  var wrappedPromise: Partial<WrappedPromise<T>> = {},
    promise = new Promise<T>(function(resolve, reject) {
      wrappedPromise.resolve = resolve;
      wrappedPromise.reject = reject;
    });
  wrappedPromise.then = promise.then.bind(promise);
  wrappedPromise.catch = promise.catch.bind(promise);
  wrappedPromise.promise = promise;
  return wrappedPromise as WrappedPromise<T>;
};

Your specific implementation may require tweaking, but the general concept remains consistent.

Live demo available

Be sure to refer to TypeScript's definition of Promise for additional insights and potential refinements...

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

Combine Two Values within Model for Dropdown Menu

I am currently facing a situation where I have a select box that displays a list of users fetched from the backend. The select box is currently linked to the name property of my ng model. However, each user object in the list also contains an email proper ...

Angular 14: A collection and schematic must be provided for execution to proceed with the process

I've recently started learning angular. After installing the latest version, I created an app called "test" using the command ng new test. Next, I opened the app in Visual Studio Code and tried to create a new component by entering the command: ng g ...

Error type inferred by TypeScript

I am currently in the process of learning TypeScript, and I encountered some errors in the code below: Error: Unexpected token. A constructor, method, accessor, or property was expected. [ts] Declaration or statement expected. class duckType{ public ...

Javascript's ParseFloat function returns a string instead of a number

I have an array retrieved from an API that looks like this: x = [0, 12.1, 23.45, 100.23, 13.99, 90, 0, 16.1] I need each number to have a decimal point up to two places, such as 0.00 or 12.10. Here is what I tried: x = x.toFixed(x); However, this conv ...

How can you eliminate the prop that is injected by a Higher Order Component (HOC) from the interface of the component it produces

In my attempt to create a Higher Order Component, I am working on injecting a function from the current context into a prop in the wrapped component while still maintaining the interfaces of Props. Here is how I wrap it: interface Props extends AsyncReque ...

Execute a function in Angular2 every 10 seconds

I've been working on a project that requires a Timer to make an API call every 10 seconds. I tried using setTimeout, but encountered an issue where it turned into an infinite loop. Even when navigating to another page, it continued to execute the if c ...

Navigating with Angular 6 using routerlink in a child module with router-outlet specified in the parent component (app.component

I'm currently working with the RouterModule and encountering an issue with the routerLinks. The problem I am facing is that the routerLinks are not functioning properly (the anchor tags are not clickable). This issue arises because they are located w ...

Relocating the node_modules folder results in syntax errors arising

I encountered a perplexing syntax error issue. I noticed that having a node_modules directory in the same location I run npm run tsc resolves the issue with no syntax errors. However, after relocating the node_modules directory to my home directory, ~ , a ...

Adding a custom property to a React component

Currently, I am facing an issue while attempting to modify an MUI component. Everything works smoothly until I execute the build command, at which point it fails. I have experimented with a few variations of this, but essentially I am looking to introduce ...

Custom Joi middleware in Express v4 is failing to pass the Request, Response, and Next objects

I am currently in the process of developing a unique middleware function to work with Joi that will be placed on my routes for validating a Joi schema. In the past, I have created middlewares for JWT validation without passing any parameters, and they wor ...

Guide on utilizing the "window" attribute within Angular framework

Recently, I came across a neat "Scroll back to top" button that caught my eye: https://www.w3schools.com/howto/howto_js_scroll_to_top.asp Despite being new to Angular, I wanted to give it a try and implement this feature myself. However, every attempt I ...

What is the best way to emphasize a selected row in a table when clicked using both Bootstrap 4 and Angular 6?

My Bootstrap table is styled with table-hover and all functions as expected. The .table-hover class activates a hover effect on table rows within a <tbody>. Additionally, I have implemented the following method: listClick(event, newValue) { this ...

Invoke an ActionCreator within a different ActionCreator

Calling an ActionCreator from another file is proving to be a challenge... The products.ts file contains the ActionCreators and Reducers for Products... import { setStock } from './Store.ts'; //.... export const addProduct = (product: IProduct) ...

Comparing Redux and MVC models in software architecture

A new project is on the horizon, and the Product Owner has suggested using Redux for state management. However, I am hesitant to embrace this suggestion as I fail to see the advantages compared to a model-based approach. For instance, instead of utilizin ...

Issue with Google Node SDK Calendar freebusy query failing to display event times for private calendars

I have been attempting to retrieve the free/busy times for a user whom I previously oauthed and stored their access token and refresh token in my database. However, every time I make the request, I consistently receive the following response: data: { ...

What is the process of determining if two tuples are equal in Typescript?

When comparing two tuples with equal values, it may be surprising to find that the result is false. Here's an example: ➜ algo-ts git:(master) ✗ ts-node > const expected: [number, number] = [4, 4]; undefined > const actual: [number, number] ...

Error: In Angular and Typescript, the function this.$resource is not recognized

I keep encountering a TypeError: this.$resource is not a function. Below is the code snippet causing the issue: export class DataAccessService implements IDataAccessService { static $inject = ["$resource"]; constructor(private $resource: ng ...

Batch requesting in Typescript with web3 is an efficient way to improve

When attempting to send a batch request of transactions to my contract from web3, I encountered an issue with typing in the .request method. My contract's methods are defined as NonPayableTransactionObject<void> using Typechain, and it seems tha ...

Sharing properties between components

While this topic has been discussed extensively, I am still struggling with my specific example. In my setup, I have a react-select component nested within another component, which is then part of the larger App component. SubjectSelect.tsx export default ...

Generating a linked pledge with AngularJS

I need to create a linked commitment for my service provider: this.$get = function($q, $window, $rootScope) { var $facebook=$q.defer(); $rootScope.$on("fb.load", function(e, FB) { $facebook.resolve(FB); }); $facebook.api = functi ...