Why async functions don't require a 'then' keyword

There are two functions that produce the same outcome:

const p1 = async () => {
  return 1;
};

const p3 = new Promise((resolve, reject) => {
  resolve(1);
});

console.log(typeof p1.then);
console.log(typeof p3.then);

It is surprising that both functions do not transpile to have a "then" property:

https://i.sstatic.net/cfIHX.png

However, vs-code's intellisense considers them both as promises:

https://i.sstatic.net/YUKIo.png

https://i.sstatic.net/x4wyL.png

We can even ensure that the return type is the same if we're explicit about p3:

https://i.sstatic.net/FcKy6.png

Now, a Promise is "thenable" by definition, right? This becomes important as I have an inferred interface in Typescript from the following function:

export const DELAYED = "WAIT_IN_PARALLEL_DELAYED";
export function delayed<T = any>(delayedPromise: () => Promise<T>) {
  return {
    delayed: DELAYED,
    start(resolve, reject) {
      delayedPromise()
        .then(resolve)
        .catch(reject);
    }
  };
}

I expected that passing in:

 const test = () => async() => 1;

to the function delayed(test) would be acceptable. However, it is indicating that "test" does NOT have a ".then" property. Can someone help me pinpoint the issue in my logic?

Answer №1

At the outset, it's important to note that p1 and p3 are not identical. While p3 is a type of Promise with a then method, p1 is actually a function that returns a promise, making it a function rather than a promise. This is similar to the scenario with p4 = () => 5, where p4 is a function and not a number.

Essentially, your delayed function necessitates the input of a function that produces a Promise, even though it might seem more straightforward to just provide the Promise itself. In addition, your test function doesn't align with the type of delayedPromise. Why is that?

This misalignment can be understood by looking at your definitions:

delayedPromise: () => Promise<T> // a function that returns Promise<T>
const test = () => async() => 1; // a function that returns a function that returns a Promise

To rectify this, test should be defined as:

const test = async() => 1;

I hope this clarification aids your understanding.

Answer №2

The absence of "then" in async functions

When async functions are called, they do not directly return promises but instead return a promise object with a property called then.

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

Ways to effectively implement a function type specified in an interface

Consider the following interface: interface MyProps { onEvent: (name: string, data: any) => void; } Is there a way to utilize the function type in order to avoid unused parameter errors during compilation? eventHandler = (name: string, data: any) = ...

Tips on invoking Bootstrap's collapse function without using JQuery

We are facing a challenge with our TypeScript files as we have no access to jQuery from them. Our goal is to trigger Bootstrap's collapse method... $(object).collapse(method) but without relying on jQuery. Intended Outcome //Replicates the functio ...

Angular2 (RC5) global variables across the application

I am seeking a solution to create a global variable that can be accessed across different Angular2 components and modules. I initially considered utilizing dependency injection in my `app.module` by setting a class with a property, but with the recent angu ...

Creating a new list by grouping elements from an existing list

I have successfully received data from my API in the following format: [ {grade: "Grade A", id: 1, ifsGrade: "A1XX", ifsType: "01XX", points: 22, type: "Type_1"}, {grade: "Grade B", id: 2, ifsGrade: &quo ...

Tips for enabling custom object properties in Chrome DevTools

In my typescript class, I am utilizing a Proxy to intercept and dispatch on get and set operations. The functionality is working smoothly and I have successfully enabled auto-completion in vscode for these properties. However, when I switch to the chrome d ...

In Typescript, you can easily group a string into sections that consist of digits like 345-67, along with text containing a

I have a string that looks like this: "[111-11] text here with digits 111, [222-22-22]; 333-33 text here" and I am trying to parse it so that I can extract the code [111-11], [222-22-22], [333-33] along with their respective text descriptions. The challeng ...

How should trpc query calls be implemented in a Next.js application for optimal performance?

Transitioning from pure frontend React to Next.js, I am currently working on implementing trpc calls to the backend. While this is a familiar process for me, it seems that the approach I've been using may not be appropriate in this case. const [weight ...

Deleting an element from an object in TypeScript

Is there a way in TypeScript to exclude certain elements (e.g. 'id') from an object that contains them? ...

Exploring the power of Angular 10 components

Angular version 10 has left me feeling bewildered. Let's explore a few scenarios: Scenario 1: If I create AComponent.ts/html/css without an A.module.ts, should I declare and export it in app.module.ts? Can another module 'B' use the 'A ...

What is the best way to export a default object containing imported types in TypeScript?

I am currently working on creating ambient type definitions for a JavaScript utility package (similar to Lodash). I want users to be able to import modules in the following ways: // For TypeScript or Babel import myutils from 'myutils' // myuti ...

Definition of type instantiation in TypeScript

When utilizing the mynew function with a specified array of classes, I am encountering an error related to defining unknown. How can I modify this definition in order to eliminate the error? export interface Type<T> extends Function { new (...arg ...

Show a specific form field based on the chosen option in a dropdown menu using Angular and TypeScript

I am looking to dynamically display a form field based on the selected value from a dropdown list. For instance, if 'first' is chosen in the dropdown list, I want the form to remain unchanged. However, if 'two' is selected in the drop ...

The issue of inconvenience arises when dealing with `as const` arrays, as the readonly T[] is not directly assignable to T[]. The challenge lies in how to effectively remove

I encounter this issue repeatedly (playground link): const arr = [1,2,3] as const const doSomethingWithNumbers = <T extends number[]>(numbers: T) => {} doSomethingWithNumbers(arr) // ^ // Argument of type 'readonly [1, 2 ...

angular directive to receive an object

When I have a table and click on a row, the information is supposed to be displayed in a different component using the @input decorator. However, instead of displaying the correct result in my other component, I am getting [object Object]. table.html < ...

Why does HttpClient in Angular 4 automatically assume that the request I am sending is in JSON format?

Currently, I am working with Angular 4's http client to communicate with a server that provides text data. To achieve this, I have implemented the following code snippet: this.http.get('assets/a.txt').map((res:Response) => res.text()).s ...

Issues with Angular Reactive Forms Validation behaving strangely

Working on the login feature for my products-page using Angular 7 has presented some unexpected behavior. I want to show specific validation messages for different errors, such as displaying " must be a valid email " if the input is not a valid email addre ...

Passing a service into a promise in Angular 2 using TypeScript

Is there a way to pass a service into a promise? I am currently working on a promise that will only resolve once all the http requests are complete. However, I am facing an issue where this.jiraService is undefined. Is there a method to pass it to the co ...

What could be causing my code to fail in retrieving lists from the SharePoint site?

I've been attempting to retrieve lists from a SharePoint site using the provided code, however, the list isn't appearing in the response. Could someone please offer assistance with this issue? I have tried various other solutions, but the problem ...

The task of mapping an array of objects with nested values using JavaScript is proving to

Attempting to convert an array of objects with nested values in child objects like: const objs = [{ "B": { "value": 1, }, "D": { "value": "45" }, "E": { "value": "234" }, ...

Tips for sending data to CSS in Angular

I have an Angular application where I need to calculate the width of an element and store it in a variable called finalposition. Then, I want to move this element to the left by (finalposition)px when hovering over it. How can I achieve this styling effect ...