TypeScript feels worth it until you use something like Elm, then you realize just how lacking and TypeScript's type system truly is.
I have grown rather weary of type systems that don't require you to be exhaustive and, for my money, types like `Omit` and `Pick` are nasty hacks that just let you pretend like you aren't doing dynamic types, something TypeScript does a lot. The TypeScript pattern of `someFunc<typeof someInput>` is just dynamic types with extra steps. Using `any` wouldn't really lose you much of anything, the "type" is just "whatever this input is". That's not a real type, that's a dolled-up dynamic type. But hey, it typechecks!
TypeScript's major weakness is that it doesn't want to break away from Javascript. That strict dedication to being a superset means the type system explodes into ten thousand builtin types the come, seemingly at times, from nowhere, simply to control for the wildness of Javascript. It feels like a joke sometimes, and like I need to have encyclopedic knowledge of all these highly-specialized types that are included in the language and are often being used in the background.
This leads to nearly impenetrable error messages regarding types, especially if you have a stack trace involving more than one object/record type (whatever you want to call it), it will expand all of them and just, no. It's unreadable. It can be read, but it cannot simply be grokked.
TypeScript just doesn't impress me. I get far better results from other languages for a whole lot less work. TypeScript claims to want a balance between correctness and productivity but the language gives me neither of those things. My typical experience is that I wrote almost the same amount of actual code, but now also with types. Elm lets me write far less total code. Less code means less bugs and more productivity, and better types and better correctness is what gives you those things.
I think this misses the point somewhat, I think even the typescript people will agree, yes, you CAN pick another language and get better type support ( amongst many other things ). But typescripts goal is to be a superset of javascript, which has resulted in many many libraries now shipping with typescript type definitions as officially supported things within libraries. Elm ( or any other client side language) simply hasn't had that kind of impact. Yes it does still have a bunch of problems inherited from the nature of javascript. Sure, you, as an individual might get good results with your tech choice.
So I think the main thing is typescript should make things better in the javascript world, but due to its ability to gradually adopt typescript syntax over javascript syntax you can live in a middle ground where it's not going to do much for you (or even make it worse).
Ultimately I think compiled WASM based languages are going to take over, but we aren't there yet.
A big problem is that elm has questionable stability as a project. It's mainly one person, and not a lot of mainstream usage. The biggest projects mentioning elm are ones related to the main programmer.
Typescript on the other hand has had massive growth and has been adopted by a large amount of libraries. Now, web ts/js libraries usually suck but it still speaks to the overall health of the language in a community. Even then, typescript still only has a very small percentage of usage.
Elm is basically a rounding error on some of the surveys I've seen.
Long term support, tooling, etc are often much more important for languages past a threshold. Typescript as a language may not be super exciting. Typescript as a technology is wonderful.
Sadly, Elm was never able to build a true core development team outside of Evan. Or at lest it didn’t do it fast enough.
Evan is a smart programmer but not a strategic organizer or a communicator.
As a result, one of the most exciting and promising approaches to front end development was relegated to a nice-toy project status.
If you want to take the risk of building something using Elm’s approach, you’ll do it with Reason.
Maybe not 100% as nice as Elm, but you’ll feel confident you’re not risking your code base and company on the whims of one person.
I still think Elm is a nice educational language for getting people (and kids) into FP.
> TypeScript's major weakness is that it doesn't want to break away from Javascript.
No, it is not. That is exactly the major strength of Javascript! It is an addition to the landscape, for people, who can make use of it.
For everyone else, there is already Javascript "successors", that break with Javascript, but compile to Javascript. But they also are a new language, or, another language. You named one: Elm.
Not so TypeScript. I can gradually upgrade my codebase. And I can reuse knowledge and components, I already have. I am so happy about Typescript. How else could I continue using ES3 on the Windows Scripting Host and have modern Javascript tooling? For me TypeScript is the "better" Javascript. An evolution, rather than an exit strategy.
I'm not really sure why you were downvoted since you raised some pretty relevant points.
> TypeScript's major weakness is that it doesn't want to break away from Javascript.
This seems to also be the source of it's popularity, it's the path of least resistance, sprinkling types on top of your existing codebase is a way easier sell.
Maybe because it's totally missing the point? It's like if I ask "is mypy worth it?" and someone answers me: "not worth it, Rust has a better type system".
Also from a business/management POV, it's quicker to migrate JS->TS than JS->Elm and easier to find TS devs (because nobody uses Elm btw) or teach TS to JS devs.
TypeScripts pragmatism is indeed its biggest strength. It is very simple to get started with converting a JS codebase into TS. This means there is a _real_ and _practical_ migration path for all the mountains of existing JS. I haven't used Elm but I would assume the cost to convert existing code is much more significant.
But TS then goes further and layers a lot of really nice features on top of the JS underpinnings. Being able to strongly type string-ly typed things are, again, such a useful feature to have for a codebase that interacts with JSON/JS.
All this said, in my experience `Record` is not very heavily used, but is really useful when you do need to reach for it.
I haven't played with Elm, but my experience with ReasonML matches yours. I made some small but non-trivial side projects to learn ReasonML and TypeScript, and not only is ReasonML's type system vastly more satisfying, I actually found it much easier to learn (coming from JavaScript) than TypeScript is!
Typescript is entirely about being a superset of Javascript with the unique ability to implement types from very strongly defined to completely dynamic, and this can be set function by function or even line by line.
That's what led to the wild productivity and popularity. If you're answer is to just use an entirely different language then why stop at Elm? There are dozens of strongly typed languages available.
Nitpick: In the situations you described, the type is known to the compiler at compile time no? Do you have the same problem with "auto" in other languages?
Can I, in Elm, bring over my couple dozen NPM modules I use in my projects? At least what TypeScript has going for it, if not a more robust type system, is interoperability with all the other tools I need to build web applications.
Maybe not in the way JMTQ is expecting. You could bring your npm modules over and call them through Elm ports, but you’ll still have to declare type signatures of those ports and have a bit of ceremony about calling them.
It might be better to ask what those npm packages are doing, exactly. There’s a decent chance that either the npm package is filling a shortcoming of the JS standard library (e.g. moment) where that shortcoming doesn’t exist in Elm, or an equivalent Elm package exists.
I have grown rather weary of type systems that don't require you to be exhaustive and, for my money, types like `Omit` and `Pick` are nasty hacks that just let you pretend like you aren't doing dynamic types, something TypeScript does a lot. The TypeScript pattern of `someFunc<typeof someInput>` is just dynamic types with extra steps. Using `any` wouldn't really lose you much of anything, the "type" is just "whatever this input is". That's not a real type, that's a dolled-up dynamic type. But hey, it typechecks!
TypeScript's major weakness is that it doesn't want to break away from Javascript. That strict dedication to being a superset means the type system explodes into ten thousand builtin types the come, seemingly at times, from nowhere, simply to control for the wildness of Javascript. It feels like a joke sometimes, and like I need to have encyclopedic knowledge of all these highly-specialized types that are included in the language and are often being used in the background.
This leads to nearly impenetrable error messages regarding types, especially if you have a stack trace involving more than one object/record type (whatever you want to call it), it will expand all of them and just, no. It's unreadable. It can be read, but it cannot simply be grokked.
TypeScript just doesn't impress me. I get far better results from other languages for a whole lot less work. TypeScript claims to want a balance between correctness and productivity but the language gives me neither of those things. My typical experience is that I wrote almost the same amount of actual code, but now also with types. Elm lets me write far less total code. Less code means less bugs and more productivity, and better types and better correctness is what gives you those things.