4 ms·
> Although we use Typescript to mitigate these types of bugs, when we're working with external systems, it's easy to find yourself in a situation where the type
by jtchang 3y ago
> Although we use Typescript to mitigate these types of bugs, when we're working with external systems, it's easy to find yourself in a situation where the types are lying to you.
What does this mean? If you use typescript doesn't it prevent these types of bugs?
- jackweirdy 3y agoIf a property is a string in your typescript interface but a number in your external service (api, DB, whatever) the typescript compiler would not know
- koolba 3y agoOr worse if you blindly deserialize JSON and cast it as whatever you want it to be without validation…
- ianlevesque 3y agoe.g. the norm for typescript use.
- awoimbee 3y agoTypescript does compile time checking only. Almost all TypeScript programs I've seen just decode JSON received and slap an `as SomethingType`. TypeScript is not strict, so it's easy to write but you can still get type errors.
- geraldwhen 3y agoThat’s what’s class-validator is for. You can ensure your apis are doing sensible things.
- hinkley 3y agoFor instance I am currently trying to file a patch for a TS project. It is advertised as an npm module, which means if you pass a string to a function expecting a number it will happily do string concatenation on it instead of addition. There are no internal checks because TS, but that only works if you call it from TS. Otherwise authors have a false sense of security and make bad decisions.
- thewix 3y agoThis is why I use codec libraries like zod or io-ts (purify has them built in also) at my boundaries.
- Waterluvian 3y agoThey were just accepting incoming data as-is and typescript won’t do a thing for you. Ideally you validate incoming data using jsonschema or whatnot.
- delusional 3y agoIn the static analysis space this is a fundamental issue. We can't really usefully reason about the actual system, the state space simply becomes too large. So you have to reduce your problems to some axiomatic abstraction. In type systems we mostly cut those axioms at the system boundary. This is mostly because type systems are often incompatible and therefore can't automatically be analyzed across the boundary. Imagine some pipe. You can put in some bytes and get some bytes out again. As far as you know, you have to put in 16 bit integers, and you get 16 bit integers out. You put that in your type system: int16_t communicate(int16_t in); Now what you don't know is that if you provide the remote system with the integer 0, it will send back a 0, followed by the string "hello world". Your type system can't catch that because you've never told it that it can happen. The axioms the static analysis was built on didn't match reality, and therefore the analysis itself isn't sound.