Parse, Don't Validate — In a Language That Doesn't Want You To
21 points by FedericoSchonborn
21 points by FedericoSchonborn
If JavaScript/TypeScript are fighting the style of code you want to do (either technically or ergonomically), why not choose one of gajillion compile-to-JS languages out there instead? We see Haskell, Elm, F# mentioned… PureScript, js_of_ocaml, Reason, LunarML, (& bound to be many more that I’m forgetting) in the same family the writer seems like they would rather be using, so why not just use them? They even mention the wrote a whole nother post called Why TypeScript Won’t Save You doing even more comparisons to the languages they would rather be using as well as hosting https://learnelm.dev. …Or is the comparison the whole point: to show users that TypeScript doesn’t get the job done for many to encourage adoption of other toolchains/ideas?
If JavaScript/TypeScript are fighting the style of code you want to do (either technically or ergonomically), why not choose one of gajillion compile-to-JS languages out there instead?
Pre-existing codebases, expertise of your team in a given language/corporate guidelines, less support/tooling/smaller communities. Most people don’t have the choice or time to “just choose another language”.
If you throw a bunch of FP libraries in a style that isn’t idiomatic & try to do “parse, don’t validate”… then you aren’t helping your team, but making a mess. I was tasked to do this once & the junior dev took my Option type, called .value & checked it for null defeating the whole exercise while making my life harder & readability worse. I’ve also seen a lot of projects convert to TypeScript to be ‘safer’ according to management, but those actually working with that most of their time are unhappy with it. :\
Honestly I thought this article was quite poorly informed.
The point of "parse don't validate" is to protect yourself from all kinds of things that shouldn't be able to happen, the kinds of things that would make any person want to tear their hair out by its roots. If you put all the safety in TS, none of it is real safety. It's counterproductive to do a lot of work so that your tools swear up and down that unsafe code is actually safe. It's like working to grow the size of your own blind spot: you're not reducing the potential for hair tearing, you're actively maximizing it
If you put all the safety in TS, none of it is real safety.
What do you mean by this? Is the idea that when the safety lives in TS it's compiled out and isn't present in the output JS?
You could make the same argument about a test suite, but clearly both tests and types let you prove various properties of your code ahead of time without needing to be present in the deployed bundle
If type erasure alone was the issue, you could make the same argument about Haskell.
Where I do see a problem with Typescript is that it's really quite easy to end up with data in a variable that doesn't match the TS type, basically anywhere you go across an untyped-to-typed boundary.
For example, in a fairly strict Angular+TS codebase I worked on, despite not using any, we still occasionally had issues where the fields of a JSON format HTTP response body did not match the TS type we used to represent it. Arguably that was our fault, we should've "parsed" (as in the article) to ensure the potentially freeform JSON actually matched before assigning it to our type, but there was nothing pushing us in that direction by default (and in fact it was extra work).
JS has the facilities to make an actual unbreakable guarantee (which is not compiled away). Such a guarantee is safe even when faced with untrusted, un-typed or any-typed code.
I guess the usual answer is that you have a big TS code base or you use a TS library that is not available for another language.
I'm a big fan of branded types at work - the one thing that really grinds my gears though is that I cannot create an Array or a TypedArray that is only indexable using my branded numbers, and for TypedArrays I cannot even store (or rather, load out) branded numbers into them. I don't really care what it would take - even a separate set of types like IndexArray and IndexTypedArray - I just really want that to be a thing.
At work, we have a "smart enum" and a custom array type, so you can do TArray<Foo, MyEnum>. This is C++ though.
In Zig, the std lib contains a EnumArray, which is implemented in comptime. It even gives you broader capabilities like using dense or sparse enums for indexing, and computing the right indexer at compile time.
I really started to grow on this kind of precise typing. It prevents so many logic bugs from even being introduced into the codebase.
I cannot create an Array or a TypedArray that is only indexable using my branded numbers
You can if you're willing to lie hard enough.
You can do the same with values of TypedArrays if you want.