Hacker News new | ask | show | jobs
by sir_pepe 1459 days ago
To try and limit one's use of operations on types, as suggested in the article, is not really great advice in my opinion. Sure, you would not want to actually implement and use a VM in types, but distilling rules about a program into types and then deriving the actual interfaces and signatures from those rules with operations on types? That's quite powerful.

TypeScript's type annotations are really a DSL embedded into JavaScript. And they can, and, depending on the problem at hand, should be treated as such.

3 comments

> TypeScript's type annotations are really a DSL embedded into JavaScript. And they can, and, depending on the problem at hand, should be treated as such.

I think this is the key. If treated as you describe, meaning the advanced types are well-written, well-documented, and well unit-tested as if they are "true" code, then using them shouldn't be too much of an issue.

However, I think people often just assume that the types aren't "real" code and thus the normal concepts of good software engineering don't apply and type monstrosities which nobody can understand result.

Imagine if this code[0] wasn't well-documented, fairly clearly written, and also tested. It would definitely be a liability in a codebase.

In addition, the rules of how advanced TypeScript concepts work can be quite nuanced and not always extremely well defined, so you can end up in situations where nobody even _really_ understands why some crazy type works.

[0]: https://github.com/sindresorhus/type-fest/blob/2f418dbbb6182...

Yes, while that is true, TS errors can sometimes be really clunky. And sans a debugger, it is not uncommon for me to be spending stretches of 20-30 mins almost every week trying to unravel complex type errors that span multiple pages. I recently traced a very weird error to TS changing what keyof never evaluates to in a minor version.

So yeah, using discriminated unions, branded types, mapped types etc. in moderation can substantially reduce the surface area of errors - more so than other mainstream nominally typed languages. However, trying to model and prevent every invalid state at type level can lead to a serious drain in productivity. And, I am not really sure how to draw a line between.

I think it depends how far you go: if you start encoding rules into the type system that are undecidable then you can quickly run into trouble.
To me its about readability. I agree that operations on types generally are a good thing because I find them more readable. Not using operations I've found leads to many very specific types which are hard to read and understand from the devs perspective.