I will only nitpick on the part about TypeScript not being type-safe enough, where extra fields are possible or wrong types can be sent over the wire.
io-ts [0] completely solves this issue, to the point where I don't think it's less type-safe than Rust in any practical manner. I've been writing apps in TS this way for the past year and I have quite a large codebase in production. The errors you mention do not happen.