It's not a problem with types. It's a problem with call semantics.
If `foo()` behavior depends on whether `foo` is async or not, you're implicitly introducing yield points that might lead to bugs like race conditions.
Even worse: if you're calling a sync function and you (or a library author) turns it into an async function, it will silently introduce the yield point without anybody noticing.
Both sync and async `foo()` would return a `T` so TypeScript won't help with that.
You may still have race conditions with await. It doesn’t prevent anything, though I see your point if we are talking about flow control (not just net/io) via coroutines. That is race-prone in general, but most of the code is a non-leaking ‘let; await fetch(); return’ in one way or another. If someone is writing code like:
public_state = a
[await or autoawait] task()
public_state = b
and then uses/modifies that state concurrently, maybe it’s time to pull their program design out of '90s.
Both sync and async `foo()` would return a `T` so TypeScript won't help with that.
async function foo(): Promise<string> {
return "foo"
}
async function bar() {
var s:string
s = foo()
}
Type 'Promise<string>' is not assignable to type 'string'.
I meant this. In js you just get a promise into ‘s’ and then save ‘[object Promise]’ into a database.
If `foo()` behavior depends on whether `foo` is async or not, you're implicitly introducing yield points that might lead to bugs like race conditions.
Even worse: if you're calling a sync function and you (or a library author) turns it into an async function, it will silently introduce the yield point without anybody noticing.
Both sync and async `foo()` would return a `T` so TypeScript won't help with that.