You need to do manual schema validation, just like you did with JavaScript. TypeScript adds 0 value. The type only gives you an illusion of safety, which is worse than no safety at all.
Typescript makes sure that all your code agrees with the protocol definition you have chosen. That alone is immensely valuable.
JSON is better because it allows external services to interpret the data in their own way regardless of their type system.
In a year or two, once everyone has switched to use `unknown` instead of `any` in functions which at runtime return… uhm… unknown values, we'll all be much safer. Because we'll be forced to use proper parsers and validators.
I don't know if that's commonly done in Typescript, though? It seems more common in web apps to trust your own server to send you good data.
https://github.com/gcanti/io-ts https://github.com/pelotom/runtypes
What about module boundaries between code? What about even the basics of knowing what you're passing into a function is correct?
Me, I write a lot of TypeScript. I've never written code on top of the Node virtual machine as quickly or good or as correct because I'm not stuck resorting to nonsense tests around "well, what do you do if you pass the wrong type to this function?" and I'm not validating internal arguments because TypeScript told you if it was wrong, this is not my bug. Instead I validate user input at the edges (less because of "bad actors" and more to provide helpful messages to the consumers of my libraries and APIs) and then I have a snappy and reasonably correct compiler yelling at me when I do something wrong, immediately after doing so. And because my entire ecosystem, past that scary user-input edge, is also in TypeScript, I am much more sure of the code I'm writing. And, as mentioned, I write it way, way faster.
So if you care about correctness and code quality, why is "well, input validation on the edge is harder" so much more important to you than that sort of thing?