Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a promise in an async function in TypeScript

Tags:

typescript

It's my understanding that these two functions will have the same behavior in JavaScript:

const whatever1 = (): Promise<number> => {     return new Promise((resolve) => {         resolve(4);     }); };  const whatever2 = async (): Promise<number> => {     return new Promise((resolve) => {         resolve(4);     }); }; 

But TypeScript seems to not like the second one, it says:

Type '{}' is not assignable to type 'number'. 

Is this a bug in TypeScript, or am I misunderstanding something about async functions?

like image 231
dumbmatter Avatar asked May 09 '17 23:05

dumbmatter


People also ask

How do I return a promise in TypeScript?

Use the Awaited utility type to get the return type of a promise in TypeScript, e.g. type A = Awaited<Promise<string>> . The Awaited utility type is used to recursively unwrap Promises and get their return type. Copied!

Do async functions return a promise?

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.

What is return type async function in TypeScript?

To type an async function in TypeScript, set its return type to Promise<type> . Functions marked async are guaranteed to return a Promise even if you don't explicitly return a value, so the Promise generic should be used when specifying the function's return type. Copied!


1 Answers

It's complicated.

First of all, in this code

const p = new Promise((resolve) => {     resolve(4); }); 

the type of p is inferred as Promise<{}>. There is open issue about this on typescript github, so arguably this is a bug, because obviously (for a human), p should be Promise<number>.

Then, Promise<{}> is compatible with Promise<number>, because basically the only property a promise has is then method, and then is compatible in these two promise types in accordance with typescript rules for function types compatibility. That's why there is no error in whatever1.

But the purpose of async is to pretend that you are dealing with actual values, not promises, and then you get the error in whatever2 because {} is obvioulsy not compatible with number.

So the async behavior is the same, but currently some workaround is necessary to make typescript compile it. You could simply provide explicit generic argument when creating a promise like this:

const whatever2 = async (): Promise<number> => {     return new Promise<number>((resolve) => {         resolve(4);     }); }; 
like image 120
artem Avatar answered Sep 22 '22 19:09

artem