Functions that are tagged async must be typed as returning a promise, since JS guarantees that the function will return a promise when invoked, regardless of its body.
This is a little bit more complex because you are using a typeguard, which cannot be async. One strategy to deal with this is to make your typeguard synchronous and have it take in pre-awaited results that it might otherwise await.
As an example
// what we'd like to do, obviously a contrived example
async isSomething(t: Something | OtherThing): t is Something {
const result = await someCall(t); // some async result we need to determine what t is
return result.isSomething;
}
This could be changed up to
async isSomethingAsyncPart(t: Something | OtherThing): IsSomethingAsyncResultSet {
// do some await'ing here
return asyncResults;
}
isSomethingGuard(t: Something | OtherThing, asyncResults: IsSomethingAsyncResultSet): t is Something {
// some synchronous evaluation using t and/or asyncResults
}
// kinda yucky but :shrug_emoji:
if (isSomethingGuard(t, await isSomethingAsyncPart(t)) { . . .}
Not sure this is the best way to handle stuff (typeguards requiringg async work seems a little suspect overall, honestly). You may be trying to shoehorn the type system into doing something it isn't designed for.
If your typeguard really is just () => true, you could just make it not async as well.
Promise<...>in typescript because they are actually guaranteed to do so regardless of what code you put in the function.