It is actually quite frustrating compared to some other languages, and more often than not you see that its just `JSON.parse` and hope for the best. I wish we had something like Rust's Serde or Haskell's aeson.
If you want to validate data coming over IO then your options are data validation libraries such joi, io-ts, and yup. You have to write seperate data validators on top of your types. io-ts has a way of deriving types from validators, but io-ts is often seen as quite intimidating being built on top of fp-ts.
No matter how carefully you maintain strict typing within your typscript project the moment you hit IO everything is basically `any`.
Some projects like openapi-generator might generate some validators for server respones, but I've not seen any good generators that do actual validation.
I'm not sure if apollo-graphql does responses validation? Does anyone know?
I also liked runtypes more, but it turns out composing io-ts codecs is perfectly readable, and being able to deserialize at the same time/instead of validating is very convenient.
Apollo does indeed validate responses as well as requests. If your server tries to send an object that doesn’t match the schema, you’re going to return just a 500 error, which means your clients can trust the graphql types implicitly.
Since in my current job I can’t use graphql but have to type everything in openapi, Had to resort to writing my own lib to get to the same functionality for a REST backend in TS - https://github.com/ovotech/laminar
My personal take is that io-ts _is_ typescript’s aeson, but if you’re scared of the baggage it comes with then how about giving zod a try? https://github.com/vriad/zod
For my current project, it is handled by GraphQL. Using a combination of type-graphql and code generation, I have fully round trip static types on both client and server, by only defining my model once. Even my graphql queries are checked.
It is a bit of a pain to setup, but once it is done, I've found that it works pretty well.
I use a combination of class-transformer[1] and then class-validator[2].
First transform the JSON into proper class-objects and then validate the object for correctnes.
IMHO this has nothing to do with TypeScript because in your runtime all the type information is gone and you need to validate the remote data never the less. TypeScript can help you structure your validations but you need to write them.
I use tcomb-validation[1] to validate incoming data. The downside is that it cannot use TypeScript types so you have to define the schema twice.
For me, the duplicated types turned out to be less of a hassle than initially anticipated. In many cases, I ended up with different data structures anyway because the data is transformed in the client. I think of them as transport types and client types.