As much as people complain about the TS type system’s complexity, it is just modeling real world JS. The vast majority of its complexity is hardly used in TS that doesn’t interop with existing JS, because you generally won’t write such highly dynamic code when you have to define its types. But it does allow for safer interop.
Even so, JS itself being so dynamic, TS still can’t claim full type safety.
And as much as people complain about the type system’s verbosity, many newer features are designed specifically to allow you to be much more terse while improving expressivity and safety. A great example: the satisfies operator lets you narrow a value’s type to conform to whatever it satisfies, and simultaneously widen it to whatever it adds (including anything optional in the narrower type). This is great for composition, only takes two words to accomplish. And its meaning should be immediately obvious at a glance once you know about the operator.
What I always say when someone complains about TS and we should just write JS is “When you write JS you ARE writing TS, you’re just compiling the types in your head.”
Yep, constantly. I used to do it and I honestly don’t know how I had 10% of that cognitive load capacity while I did.
(I still do it now because I inherited a huge highly dynamic set of projects, and just explaining the portion of the universe I remember at any given time is an exhausting majority of all of my weekly meetings.)
Having the type system this complicated is mostly for library builders, makes the developer experience of tools like tRPC, Zod and Prisma possible. An engineer writing business logic in TypeScript will probably never have to learn how to write (or even read tbh) complex TypeScript signatures, but benefit significantly from the solutions the type system complexity is a necessary precursor for.
It aims to be able to express the typing used in a bunch of pre-existing javascript libraries. Many/most of these were written in a "how would I solve this if the type system just let me do whatever I wanted" style (since that's what runtime dynamic typing actually does).
Even so, JS itself being so dynamic, TS still can’t claim full type safety.
And as much as people complain about the type system’s verbosity, many newer features are designed specifically to allow you to be much more terse while improving expressivity and safety. A great example: the satisfies operator lets you narrow a value’s type to conform to whatever it satisfies, and simultaneously widen it to whatever it adds (including anything optional in the narrower type). This is great for composition, only takes two words to accomplish. And its meaning should be immediately obvious at a glance once you know about the operator.