Those are my opinions, however.
This is somewhat less true in some frontend projects, where the underlying libraries/frameworks come with infectious built-in interface complexity (side-eyes React/JSX even though I quite like JSX otherwise).
Part of it may also be due to the limitations of TypeScript. Structural typing is not always the best choice. ADT support is also not the best.
Look at shell scripting. Imagine trying to apply a type system to shell scripts. It wouldn't map cleanly at all because (almost) everything is a string, and the operations define how those strings are interpreted - not the data itself.
However for what it is, shell scripting is quite useful. Most would argue it has a simple interface, simple syntax, simple concepts.
Perhaps a contrived example - my point mostly being that you can't draw conclusions like that.
Oh, I wasn’t saying the language is poorly designed. I was saying the particular JavaScript code where people complain about the TypeScript types is usually poorly designed. It’s not the types’ fault the interface is so convoluted the types describing it are also convoluted.
Like people write variadic functions that take arguments, or an options map, or a boolean, or a magic string or enum… and then say “there’s 100 lines of types describing this functiona! That’s such a pain!” And like, yeah, it is a pain understanding what your function does.
> Look at shell scripting. Imagine trying to apply a type system to shell scripts. It wouldn't map cleanly at all because (almost) everything is a string, and the operations define how those strings are interpreted - not the data itself.
Amusingly, you’d end up with a type system a lot like TS. Particularly template literal and mapped types.
> However for what it is, shell scripting is quite useful. Most would argue it has a simple interface, simple syntax, simple concepts.
I think this is the only point of disagreement for me here. I find shell scripting absolutely painful, and try to do as little of it as possible.
Everything is a string because every program deserializes and then serializes data from and into a string. But you still have expectation encoded into the tools. If not, they wouldn't be able to work together. Static typing is about making these expectations explicit.
It’s worth noting though that the TypeScript team does participate in the standards process. And Microsoft has two members on the committee.
- The pipeline operator can be used to assign to a const, to prevent further assignments. While const isn’t necessarily immutable, it is often idiomatically used to signal that the assigned value is intended to be final. The same can’t be achieved with your example without wrapping it in an IIFE, which is (IMO) much harder to follow than the pipeline operator.
- More subjectively, it (in the F# variant) encourages better interfaces. For most use cases where piping would be appropriate, it’s generally a good idea to make the data you’re processing the last parameter. This also, as the article notes, works well with partial application. Which in turn also encourages good practices like composition.