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?
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!
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.
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!
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); }); };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With