And I addressed some concerns with Typescript in a sibling comment. It is much better than plain Javascript, though.
It works fine for simple cases, but those are cases that were simple to begin with (Ok, maybe they would not be fine with CPS, but async/await is just thin sugar over promises).
To really solve the async problem, you need either Observables or monadic constructs. The former is much more mainstream and mature in the JS world right now. It's not as cute as async/await and you'll be typing more functions, but it really solves the problem altogether.
Is there any better workaround to that these days?
Ditto for apply your own types atop the results. Most are already there and only a few edge cases need to be added.
As far as writing your own types on top of those libraries, how do you ensure any amount of correctness?
Am I missing something important here?
Node.js's own libraries are a mix of events and callbacks. Some of it can been "promisified", however they have yet to start a real async conversion AFAIK. I've had to wrap some of this stuff to create async interfaces for my own code.