79 comments

[ 0.27 ms ] story [ 117 ms ] thread
The best reason for me is simple: There are more and more jobs popping up asking for TS.
For good reason: it saves a huge amount of engineering hours at an organizational level because the application data structures are codified into code so they don't have to be understood through hours of trial and error for every engineer that works on the project.
The pain of TS is when you come upon it as a noob after someone else very advanced at it created it. It seems overwhelmingly annoying and seemingly unnecessary. As you use it though and it becomes easier, you start to notice an overall net gain effect where you cease to make stupid naming mistakes or signature errors or payload confusion etc. etc. Time saved in abundance.
Not to mention the refactoring support!
I just realized that this is not about the Unix "script" command that leaves a file behind named "typescript"

If you ever have a program that outputs a lot of text but you can't redirect it to a file (maybe you need to interact with it)

Then type the command "script" and run whatever you need then type "exit" and you will be left behind with a file named "typescript" that contains whatever text was output in that terminal window.

And you can play it back!

See "info scriptreplay"

Thanks for the reminder about that. I totally forgot about it, but I'll definitely be using it more now.
TypeScript makes JavaScript a boring, "enterprisey" language. That's a really successful strategy, as seen in Java and C#.
Get deeper into the type system and avoid classes. There's still some fun to be had.

But yes: TS can not fully capture what JS is capable of.

Typescript is a superset of JavaScript. Valid JavaScript is also valid Typescript. Therefore anything that you can do in JavaScript is also possible in Typescript.

You might annoy the type checker, but if you're certain that you know better then there's always ways to disable those errors.

Of course, but that's not why you'd choose TypeScript in the first place.
To be pedantic: strict TypeScript cannot fully capture what JS is capable of. And, I'd argue, non-strict TypeScript kind of ruins the reason to use TS in the first place.
IDE support with JS is sometimes so advanced, that just changing the filename to TS makes the support worse, without any code change.

This only goes for some special cases and sadly react-redux with rematch is one of them. Typescript can not understand which types are present in my dispatch object, whereas it is possible with JS autocompletion!

Just wanted to bring up this rather curious exception to the rule.

> IDE support with JS is sometimes so advanced, that just changing the filename to TS makes the support worse, without any code change.

That’s kind of dumb on the part of the IDE involved.

I would say it makes JS bearable to use. I don't enjoy wondering whether a bug came from me forgetting to check against null instead of undefined, or accidentally overwriting an object with a string and so on.

At least 50% of runtime issues I had earlier are now type errors at compilation and fixed quickly. I'll take boring any day, JS is not a language I want to spend more time with than necessary.

I just wish the compilation was faster.

For many use cases, Python is unbearable as well. That's my point :)
Compilation is reasonably fast if you keep the TypeScript compiler open in “watch” mode, the trick is integrating watch mode with other build steps.
I can only assume this is as opposed to Javascript being as dynamic as possible. It is not my kind of fun. I thought maybe Raku (in case you did not know it before) is a language you might also enjoy. It is very expressive and has interesting concepts.
I am empathetic to many of the reasons that folks enjoy using static types in JS, and there are many pros to using TS, but I don't find the arguments here to be persuasive at all. And as an engineering manager, I find some of these to be concerning.

Point #1 might be the strongest point, but it also assumes that your entire dependency graph is also type-safe, which is rare currently in the JS world (though that seems to be trending upwards).

Point #2 suggests that the class of bugs that were caught on the front-end could only otherwise be caught at compile-time by TS. In this example, its really just a question of whether you want syntax/semantics in your code to prevent these bugs or unit tests to assert correct application behavior. You could easily make the argument that the former is more expedient, I buy that. But it's not some exclusive domain of value in favor of TS. Arguably you could be using both approaches, but I find that increased surface area of unit tests (to cover the type error burden) is de minimis in the big picture.

Point #3 is similarly concerning. I hear this a lot from newer devs, that they can breathe a sigh of relief in thinking they can go make a ton of refactoring changes to their app and know that TS will prevent them from making egregious errors. But in fact, you can easily refactor an entire application and the output can be both type-safe _and_ have the behavior changed such that it no longer meets acceptance criteria.

On balance, if we had native type annotations in JS I'd use them, but I haven't really heard convincing value arguments (yet) to just go all-in with TS.

> But in fact, you can easily refactor an entire application and the output can be both type-safe _and_ have the behavior changed such that it no longer meets acceptance criteria.

You're catching a set of errors (interface / types, method signature changes) that are difficult to catch in JavaScript without types when you're refactoring. Intended behavior is still validated with your set of unit tests.

What you've avoided is introducing a new set of bugs that wouldn't be caught without strong typing. You swapped argument order in a private function somewhere, removed or changed a parameter, etc. that isn't caught by your unit tests and introduces subtle errors at runtime that TypeScript catches at transpilation time. That IS valuable on a larger codebase.

You can claim unit tests should / would catch these errors, but rarely do unit tests catch all possibilities. They catch known and probable error conditions. The returns for time writing tests drop drastically as you try to push unit tests into the role of a statically typed compiler.

TypeScript is popular because it's minimal friction while giving you a majority of those benefits.

>You're catching a set of errors (interface / types, method signature changes) that are difficult to catch in JavaScript without types when you're refactoring. Intended behavior is still validated with your set of unit tests.

I want to challenge this a bit. Your unit test suite should also be able to catch all these things with the right assertions. There's nothing about JavaScript, in either syntax or semantics, that make these especially difficult to test for (notwithstanding some of the more famous footguns, but those are well known).

To put it plainly... If I change the argument order of a function/method, the associated unit test absolutely should fail. If it doesn't, I'd argue the test wasn't written properly.

To me, this just smells like an ergonomics preference. As in— do you prefer writing unit tests or type annotations? The latter comes with some transpiling and dependency overhead, so I've just opted for the former.

(edited for grammar)

It's not an either/or, the same way people who have access to professional editing staff probably still have a spell checker enabled in their word processor.

If I have to hunt down each error caused by each refactor to the codebase, strictly based on a stack trace, I will not be happy. Being able to run a type checker that prints a list of probably wrong spots, and being able to check my unit tests after, makes me happy.

And the overhead of introducing types is quite low, especially when using typesafe database tools like TypeORM and typesafe API tools like GraphQL.

You basically get all your types for free. The question then becomes, why shouldn't we type check?

I don't think the assertion that types are "free" or "quite low" maps to my experience with JS tooling/dependency bloat. The transpiling burden is not minimal.

I'm empathetic to the argument that because TS can find these errors easily, and descriptively, then it's a valuable tool. But your latter comment re: going through a stack trace, doesn't map to my experience with unit tests. If your test output is just a random exception in a stack trace, I would again argue that the test wasn't written correctly. This introduces an assertion burden for sure, ones you don't have to write if youre using TS, but I would posit that the exchange isn't as "free" as you claim.

Why write assertions when TS can figure them out for you?

And "tooling/dep bloat" is not a real thing. You point TSC at your code for prod, https://www.npmjs.com/package/ts-node-dev in dev. Frontend is even easier, create-react-app and Next.js and other project tools have TS support built in.

You claim its not a real thing, and yet I have many practical experiences of it being a very real thing over the last 15 years of my career. Everything from simple tooling headaches in dev, to actual shipped production bugs resultant from the dev toolchain. Pretending like there isn't a real tradeoff here doesn't really help move the needle in my original commentary, that persuasive arguments in the OP article are missing.

I also think its interesting that immediately subsequent to your comment about dep bloat not being a real thing, you link to yet another dependency to solve a problem with using TS in node dev.

As an aside for what its worth (since you mentioned frontend), all of my commentary assumes node.js dev and not the frontend. The former is what I work in day to day.

>Why write assertions when TS can figure them out for you?

I could easily just reframe this to say: "why write type annotations when you can write assertions?" — its orthogonal to all my earlier points about the OP's arguments

I think if you're of the opinion that installing any toolchain (as opposed to writing files right to disk and having Node read them as-is) is "bloat" then obviously it will be hard for me to convince you it's not. I can say, however, that though your experiences may have been valid even as recently as a few years ago, there are very few bugs in these tools these days. Moreover, TS is not a place where these bugs appear; shipping prod code from TS source is literally just stripping the types as you check them, and whether you webpack/babel/etc. afterwards is up to you. In short, "bloat" could possibly be considered a real thing in other situations, but in the context of TypeScript it certainly isn't.

Perhaps your previous experiences with these sorts of tools has affected your view of this one. I respect that. I just don't think it's relevant here.

> "why write type annotations when you can write assertions?"

Because you don't have to write type annotations most of the time (hence the "figures them out for you" that you omitted). TS infers them, even from things like database or API calls. We're not in Java land, where every type needs to be specified. TS understands what you mean, and will warn you (or configurably, throw an error) if it doesn't. It's a false equivalence.

These are all great points, thanks for digging in here.

It does sound like you give the TS community a lot of credit with respect to toolchain stability and thats nice to hear for someone like me who isn't directly involved in that community apart from browsing the issue tracker every month or so.

I'll concede that I do work backwards from the "you don't know what you don't know" bias, and given my previous experience with other type systems, I tend to privilege the status quo (e.g. our software works well, five 9's of uptime, virtually no runtime errors reported via APM, developer productivity is high, business objectives are being met, etc).

I need to work on that bias, because it can become an infinitely recursive argument.

Definitely, and there's nothing wrong with maintaining the status quo if it's working really well as-is. But I think it can be pretty surprising to folks that haven't had an opportunity to play with TS, just how powerful the tooling is. Perhaps one way to break through that bias is to start up a side project and play with it a little.
I actually have done a few projects with TS, but none of them were really put to the full professional SDLC test. e.g. managing upstream dependency changes, lots of developers contributing, business constraints, etc.

Personally I am very bullish on Deno, which goes beyond just native type system, but we'll see how that project ultimately plays out.

> Your unit test suite should also be able to catch all these things with the right assertions.

A type system lets you precisely define the structure of your objects in the same language. It's a kind of documentation of implicit information that forces you to keep it up to date and write the annotations in a standardised way. It doesn't replace tests, but it is more precise, compact and you get near instant feedback after every modification of the code. The additional transpiling step might seem like a delay, but only if you don't consider the time saved by the type checker.

When working with other developers it's also useful and gives me the structure of all their objects at a glance.

And for me writing unit tests is pretty much one of the most boring and cumbersome part of development, second only to things like reading documentation in an attempt to figure out why that one DB installation is now malfunctioning since I pushed a commit in a different project during full moon. The fewer tests I have to write the better.

> A type system lets you precisely define the structure of your objects in the same language

This is much more persuasive than anything written in the article I am commenting on. I personally still don't think this is worth all the tradeoffs for myself or team, but its a good argument for TS.

> When working with other developers it's also useful and gives me the structure of all their objects at a glance

Doc blocks also do this. A good argument could be made such that "if you're cool with writing doc blocks, why not write types while you're there?" - totally agree with that in principle. But again, in the aggregate cost/benefit analysis this is a minor win.

>And for me writing unit tests is pretty much one of the most boring and cumbersome part of development

I retreat back to comment I made about ergonomics preferences. You really dislike writing unit tests, I do not. TDD has been an incredibly impactful (and enjoyable) part of my 15+ year software journey. I started my career using strictly typed languages, and found my way out of them. Unit tests are one of the ways I maintain application integrity, which does actually (perhaps strangely for some) bring me joy. A buttoned up test suite is a very "feels good" moment for me as an engineer. Knowing I, or anyone else for that matter, can come back to the code later and both safely and confidently make changes.

Something also worth noting, that didn't occur to me previously, is that my implicit heuristic analysis here is mostly centered around production node.js apps, not front-end apps. I haven't worked with the latter on a day to day basis in many years. Theres a significant difference in the cost/benefit calculus between the two.

And a side point since we're talking in heuristics analysis... In my experience, especially my recent experience being a director of engineering & cofounder of a large technology company, runtime type errors are just not prevalent in the class of failure modes we see in our applications in production. I can't remember the last time a ReferenceError or TypeError appeared in any of our APM logs. So then the question becomes, how much time is "lost" in development when you hit type bugs (either with new code or fixing old code). This is much harder to quantify admittedly, but also seems minimal in my own experience.

> I want to challenge this a bit. Your unit test suite should also be able to catch all these things with the right assertions.

In general, tests can only find bugs, not prove the absence of them. Type systems, on the other hand, can prove that certain classes of errors cannot exist in the code. They are complementary, you want both.

That being said, I don't think TypeScript's type system is sound, so it's probably not really giving you that benefit.

You make a good point, that theres an inversion of responsibility here. Type systems can infer correctness, test suites have to prove correctness. I'm not sure this makes the toolchain overhead tradeoff a defacto major win, but its persuasive for sure.

Curious if you could elaborate on why you don't think the TS type system is sound? I'm not familiar with any arguments to this end currently.

It is unsound. One of the most impactful unsoundnesses is when you cast one array type to another compatible but not exactly equivalent type, and then write to the array. In Flow (another type system) you simply can't do that without making the array read-only at type level. In TS, they decided to allow this for ease of use purposes.

Just in general, the TS team optimizes for a balance of bug catching and usability. It is a compromise.

Flow is a much more advanced type checker that works even harder at inferring types and eliminating bugs at the type level. It's very cool! But its community is much smaller, the tooling isn't nearly as good, and it has some major performance issues. My workplace is migrating away from it in favor of TS, which is good enough without being too slow or incompatible with our tools.

> In this example, its really just a question of whether you want syntax/semantics in your code to prevent these bugs or unit tests to assert correct application behavior.

You need to test behavior even when typing is correct, even if behavior tests will often also reveal type bugs.

Still, type checking is more reliable at catching type errors, and does so earlier than even run-on-every-save unit tests. But it doesn't remove the need to test to assure correct behavior.

I totally agree with the sentiment that unit tests and type checking are not mutually exclusive and, in fact I'd go further to say, are mutually beneficial. I've said this elsewhere on this topic that if JS had native types, I'd probably use them.

The assertion I am making here is a little more nuanced, insofar the premise of my argument is that as unit test coverage can and does offer a reliable (if not more verbose) way to assert type correctness of an application. Given that premise, I think its a deductively valid conclusion to make that the tradeoffs of introducing a significantly dense transpiling toolchain to the same application may not always be worth it.

I don't mind TypeScript as a language that much these days. I mean, Java basically won and we're programming in it, no matter whether the files end in .java, .php, .cs or .ts, what matters is the UbiquitousDomainLanguageTermInjectedAbstractionFactory before that extension.

This greases the wheels for you with excellent IDE support and a plethora of bootcamped developers/interns.

But there are two things that still bother me: First, it's the usual language-as-a-product release cycle we have these days. I'm not saying that you should have a new language version including ECMA/ANSI spec every decade or so, but new features coming in every few months/weeks causes some friction. Especially in a language that tries to play catchup with free-form argument passing by trying to encase all that in semi-proper types.

And the second and major one: There's a certain kind of "smell" that use of TypeScript causes for me. On the frontend, it often means that it's way too complex, needlessly isolated and probably should be replaced by other techniques. And on the backend -- why are you using TS there in the first place? Compatibility with JS shouldn't be an issue there, you're not running this in your clients browser. Just because the frontend bloat I just mentioned caused Google to tackle this by throwing all the SmallTalk VM writers on this peculiar sacrificial pyre and you got a speedy runtime out of it?

I think you would opt to use typescript on the backend for the same reason you would use it anywhere. You do end up with this awkward transpilation step to turn it into JS for production use, which is very fair to argue, but I hope nobody is running nodejs services in production directly from typescript source.
Type checking doesn't necessarily make your code look like Java. TypeScript enhances refactoring regardless of whether you're OOP or functional.

Your comments about frontend TS don't seem super coherent to me, but if my read is correct you just don't like that there's a bunch of code on the frontend. What does TS have to do with that? Even a short program will benefit from type checking.

Your comments about TS on the backend make even less sense to me. It's a language with a fast runtime, but it's also easy to develop with and has some really delightful tooling. If you don't like it, you're not required to use it. If you don't like JS, what does that have to do with the type checking of TS?

Either I'm misreading your comment or the comment is incoherent; either way, I don't get it.

> TypeScript enhances refactoring regardless of whether you're OOP or functional.

I've just seen way more TS code that looks like Java than code that's C-styled Haskell (and we have/had transpiled languages that were more aimed at this, like Elm or Purescript). And also way more programmers that can do the former than the latter. This really isn't my major area of complaint here, if at all. You have large projects with plenty of programmers, so you both want to express the common micro- and macro-patterns and have solid IDE support to help you analyze and refactor that.

This isn't a bad thing. I sometimes wish it would be different, but that's my "spare time philosophical meandering" part, not the part of me that gets me paid.

The whole shebang of TS add-ons, its ES20xx underpinnings and the tooling surrounding it is well suited to bigger programs. I enjoy programming it it more than some other languages. The ambivalency of my initial paragraph isn't a reflection of TS's specific weaknesses or strengths, but with some organizational paradigms.

And yes, type-checking can get you something even for small programs, and all the people doing it to make their laser-focused progressive UI elements bullet-proof can be happy and proud about it, but I doubt that TS would've been written just for those lucky few.

As it is -- and that's why we got blog posts like this -- TS is often a step for bigger frontend projects, either from the start, or migrating ones that grew a bit too much. Again, a good way to use the language, and better than plenty of alternatives. Is it better than not having a lot of those problems in the first place because might not always need a SPA or heavy-weight components?

>It's a language with a fast runtime, but it's also easy to develop with and has some really delightful tooling.

Compared to Java/C#, if you're doing orthodox enterprise, or Elixir/Rust/etc if you're not? I mean, with esbuild etc., it's not as bad as it was a few years ago, but without the argument of "full-stack", I wouldn't see myself picking it in a clean room situation.

I hear that, and I don't disagree with much of it. Just here to say that I work with a codebase that's typechecked and functional :)
Are they planning to implement pattern matching in ts? It seems like such a good fit for language type system
I don't think that's possible since types are not present at the runtime. They are just stripped away during compilation
It would still be possible as long as all the necessary information is available at compile time.
Dispatch during pattern matching happens at runtime, which requires some means of discriminating the matched values with run-time information. Typescript doesn't provide any more runtime type information than Javascript does, and so it can't see the difference between "Object" and "Object" unless the object has fields that allow it to, such as the class constructor or programmer-specified values. I don't think that the compiler adding additional information to discriminate types other than what JS already provides fits with the design goals of Typescript being a language that only adds static typing.
I hope so. As a Rust fan I was glad I learned TS for the situations I do more web-focused work. The union types are usually good enough as enum replacement, but good pattern matching would be yet another improvement.
Not any time soon AFAIK. TS aims to be syntactically identical (minus the type system obviously) to JS, so no new constructs.

It’s not clear it’d be worthwhile, anyway - TS doesn’t support algebraic data types directly, which is the big use-case for pattern matching; and the type system is smart enough, with some careful massaging, to do exhaustiveness-checking when using ifs or switches and the standard pattern for simulating them.

At this point TS is trying to keep runtime syntax in line with TC-39 (the language committee in charge of JS) proposals that reach Stage 3 (and thus likely to reach Stage 4 and general acceptance/use in the browser).

There is currently a Stage 1 proposal for a pattern matching syntax presented to TC-39. If it reaches Stage 3 then it is presumed likely Typescript will implement it.

https://github.com/tc39/proposal-pattern-matching

Definitely respect the author for admitting he was wrong, but it's also scary to see how strongly people can feel about tech they clearly don't understand.

Like most of us, I've been there myself in multiple occasions. It's not something I'm proud of and I'm grateful this behavior wears off when getting more experienced.

If you think 'this sucks because I don't understand this', chances are it doesn't really suck and you need to either learn more or shut up.

> If you think 'this sucks because I don't understand this', chances are it doesn't really suck and you need to either learn more or shut up.

This happens quite often in every facet of our society.

> it's also scary to see how strongly people can feel about tech they clearly don't understand

I don't think it's actually that unreasonable to have a gut reaction to yet another language, yet another toolchain, yet more processes to run on your code before it's actually usable. The language has to make its case. And yes, if you don't listen to the case then that's on you.

Typescript wasn’t just another language. It was greatly anticipated by many frontend devs that already worked with typed languages in other environments.

It filled a very obvious niche.

idk i think its good to be like wtf but then have enough people that use it to get you wondering more... then eventually winning you over. You only know in hindsight if it was worth it to you but then we like to justify that it was before we went through it. I think of it like the tech is earning your respect, not the other way around. It helps me sleep at night in believing i'm not a total tool whether its true or not.
IDE intelligence for React component props is one of benefit of a library written with TS.

TS to me is a nice to have feature on top of JS.

My point is, if the type system doesn't work with Javascript, then it's the trouble.

Typescript is getting more and more popular. I wonder if there is leeway to have this introduced into browsers to be run directly. I can see Microsoft doing it with edge, and possibly provide an upstream patch to chromium.

This might be unpopular opinion, but personally I'd love for JavaScript to be completely replaced with TS or something like it.

If that is indeed the case, I could see myself using TypeScript for everything. I generally dislike front-end tooling and how complex everything is, with everything having a build process (and CLI for some reason). For this reason alone, I avoid TypeScript when I can.
Has it been a while since you've done frontend development? For many use cases it "just works" now - webpack, the TS compiler, ESLint, React etc. is all well integrated
Definitely has been at least a year and a half. The last "proper front-end" thing I tried was ReactNative, and found that quite horrifying. After that, all I have written is ES5 JS that supports every browser I can think of.
Even just the ability to parse and run TS (without type necking it) would be spectacular. I hope you're right.
And we've come full circle back to VBScript in the browser.

Not to worry! Google won't let that happen. They'll push for Dart instead.

I keep looking for redeeming values in typescript but i keep getting disappointed. Typescript fundamentally fails at its one main mission; to make JavaScript typed, and in doing so, introduces issues much bigger than the "issues" it is trying to solve. (the fact that JavaScript is not strictly typed is not an issue, its a feature, although it also has its drawbacks)

Firstly, the simplest problem to fix with typescript would be to remove the "any" type, with that in the language, it lets lazy developers be lazy and negates the fact that you have typing in the first place.

Secondly, and this is the difficult one to solve, the types can lie to you. Typescript would need to implement a runtime checking system, and i dont see how that can be done without significantly hampering performance and bundle size. I know you can do type guarding and the likes, but you can do that in regular JavaScript as well.

I disagree with this.

Regarding the "any" type, it's a crutch to migrate existing codebases that started out without Typescript. Every team I've been on I advocate against using it in production code; some teams are better about this than others but it's up to the team how lax or strict their implementation is

As for runtime type checking, Typescript has not set out to replace the JS runtime. JS remains the lingua franca for dynamic content on the web, Typescript can help you write it better and incur virtually no overhead from it by compiling to plain JS. When I worked with financial applications we followed the strictest typing we knew to implement and in my time there (2.5 years) we had zero runtime bugs. It's a great tool and it works

>> Firstly, the simplest problem to fix with typescript would be to remove the "any" type, with that in the language, it lets lazy developers be lazy and negates the fact that you have typing in the first place.

I remember when TypeScript was first introduced. 'any' is what allowed it to become the player it is today, because you could use the entire JS ecosystem with very little rework. If you'd of had to redevelop everything up the stack to primitive types it never would have gotten traction.

How is this any different from strongly typed languages that ultimately resolve to 'object'?

Your arguments sound a lot like letting better be the enemy of perfect. TS doesn't have to have runtime type checking (I'd argue it should not) to be a huge productivity gain.

In that sense I guess you are right, One could also argue that it is possible to write JavaScript in such a way that gives some of the same benefits as TypeScript, but that requires more discipline, and it probably scales badly with larger teams.

I guess i might just have to go on the same journey as OP...

I'm a developer with 15+ yrs of experience in the web, and I'm definitely not smart enough to understand TypeScript. It seems like only 9000 IQ geniuses can be productive in it, especially if you're starting a project from scratch.

Coming from a C/C++ background originally, quite frankly I don't see the supposed benefits of static typing, and in fact I'm intimately familiar with how type systems can be abused to terrible effect (on code quality and developer morale). IDE support is great until your IDE is a bloated mess (Jetbrains, Visual Studio, etc.).

I have recently picked up ClojureScript and it's a lot easier to understand than TS and incredibly productive to use in real life. No static typing in sight. Just my own little field report, I don't expect to convince any hard-core TS fans out there to switch. Do what feels right!

What part of typescript requires a 9000 iq to understand?

Some of the special types are tricky and make my head hurt but most people will just consume them through autocomplete.

The only thing I miss from transitioning our frontend from React to Blazor is the typescript type system which I always thought was a joy.

Funny, I have the reverse feeling, where Typescript is (mostly) intuitive; whereas I admire Clojure and want to love it, but it keeps bouncing off my C-infused brain.

I have definitely seen type definitions tortured within an inch of their life, especially in third-party libraries, with multiple layers of generics and utility types and unions until it does take a 9000 IQ to parse them (or worse, figure out why a given data structure is throwing a type error).

While I've come to enjoy the "safety net" and autocompletion of strong types, I've discovered what I really want is meta-programming guard-rails. For instance, while I can define `type Foo = 1 | 2 | 3`, I'd like to be able to do something like `type Foo: number = x => x > 0 && x < 4`, with arbitrary meta-logic that be checked at build time, no differently than preventing coercing a string to a number. The full scope of what I want is probably NP-hard (`1 | 2 | 3` does not actually prevent `foo += 3`!), in addition to the constraints of the JS compile target, but I can dream. :)

I totally understand the fascination with type systems. It's just that in my experience, the people are have the most success with intricate type systems are much smarter than I am ¯\_(ツ)_/¯
As someone who has written tens of thousands of lines across both ClojureScript and TypeScript, this baffles me. I can definitely understand why someone would prefer CLJS, but it has a way higher barrier to entry than TS.

If you're smart enough for Clojure then you're smart enough for TypeScript. That doesn't mean you have to like it though, but you don't have to hide that distaste behind incendiary exaggerations about TypeScript only being suitable for superhuman geniuses.

The overwhelming evidence is that TS is popular _because_ it is a safer and easy-to-understand alternative to JS.

I was exaggerating; however, I also learned TS and CLJS at the same time and walked away utterly confused with TS and absolutely loving CLJS.

I'm a solo dev-- TS probably gets a lot more useful when there's a team of people working together. That would justify the barrier of entry, which was too high for me.

The big problem with typescript friction. It imposes another layer if you write in typescript. In most cases (Deno excepted?) you then convert your code into JavaScript. In order to use all the current JavaScript (libraries and frameworks) you still need to know JavaScript.

And if you write code in typescript the number of people who can easily understand your code is dramatically reduced. The pool of people you can hire is now dramatically reduced.

In my opinion the cost/benefit analysis to too high at this point.

Love TypeScript.

tsc by itself is amazingly fast. Writing stuff in TypeScript has huge benefits, you can still publish your packages so they work in plain-old ES. Interfaces that define structure of objects go a long way to reign in a codebase of unknowns.

Also, various benefits when editing: Type-based checks via tsc and linter, autocompletion (life saver). These things add up quickly in a big codebase.

That's not to speak of utility functions: https://www.typescriptlang.org/docs/handbook/utility-types.h...

I will nitpick one area: generics. While I use them a lot in practice, I seldom write new ones. Example:

In DefinitelyTyped's definitions for @types/react, it makes sense to have a generic in React components. This lets the user pass-in their own interface for their props, e.g.

    const MyComponent: React.FC<{ isFirst: boolean }> = ({isFirst, children}) => (
      <div className={`${isFirst ? 'first' : 'after' }`}>{children}</div>
    )
Declarations for React's FC (points to `FunctionComponent`): https://github.com/DefinitelyTyped/DefinitelyTyped/blob/9d56...

In the case of a widely used library, generics make sense at scale. It's reused and components revolve around the shape of props. Not to mention, DefinitelyTyped's superb community, continuous integration and maintainers around the globe.

Microsoft keeps pushing open source forward in so many ways.

Anyway - Outside of that, I've come to eschew writing new generics internally. The reason why is complexity not being worth the trade offs. I'd rather use generics already available (see utility types above). Less cognitive overhead.

TypeScript exists only so low cost shops can offload the front-end to Java and C# developers. Throw in Angular and it takes full week to create a sidebar. After all it'll still somehow be fault of JavaScript.
does anyone knows how to set up typescript properly with Vim? I tried and looks like I have to set up a bunch of things, making Vim almost as an IDE when I just want to some types on my arguments. I felt like typescript is a VSCode product because how easy they work together. I tried Flow with Vim and it was super easy and straightforward. I hated how complicated and bloated it felt to setup Typescript with Vim. Can someone please tell me how am I wrong?
Typescript is fun because when something breaks I get to play “am I stupid or is Typescript?”

It seems to be about 50/50 and I get a little ego boost when it’s not my fault. Go is no fun, when something breaks in Go I know for sure I did something stupid.

My favorite is when Typescript/Angular magically fixes itself, which I swear happens even though nobody believes me. Sometimes I think JavaScript held together with duct tape might not be completely fool-proof.

That said the “tele-sense” or whatever it’s called that tells you the errors as you type is truly awesome and so I put up with the weirdness and occasional wasted time.

I would take out the IDE stuff today. They can handle dynamic languages really well now.

On the front-end, types are just too cumbersome, especially if you’re doing Agile and demos are part of the workflow. So many changes, it’s a total drag to rewrite.

On the backend, changes aren’t usually so drastic, so the type tax isn’t so bad.

And yeah, there is a cost to using types. This war was fought long ago. In the end, as always the answer is: “it depends”