Since TypeScript is a superset of Javascript and 'Type' would be removed in the resulting js files, so I guess playing with 'type' would not work like this, right? Also, is there any better way to do it other than having two different methods?
type VoidToVoidFunc = () => void;
type VoidToPromiseVoidFunc = () => Promise<void>;
async function add(func: VoidToVoidFunc | VoidToPromiseVoidFunc) {
if (typeof func == typeof VoidToVoidFunc)
func();
else
await func();
}
add(() => console.log(1));
As you can see here, when a non-thenable value follows await
, an already-fulfilled Promise
is constructed and used.
So the simplest implementation is to await
the result of the function call. Indeed, await
wraps a value in a Promise
if it's not already a Promise
:
type VoidToVoidFunc = () => void;
type VoidToPromiseVoidFunc = () => Promise<void>;
async function add(func: VoidToVoidFunc | VoidToPromiseVoidFunc) {
await func();
// Do something else
}
add(() => console.log(1));
This behavior is correctly typed by TypeScript, indeed when you write const test = await func();
and hover the variable, its type is correctly inferred to void
.
I guess the internal implementation of the type returned by await
must look like something like this: type Await<T> = T extends Promise<infer R> ? R : T