Ask HN: Is TypeScript worth it?

365 points by roberttod ↗ HN
I have been using TypeScript for a few years now, and I haven't yet been convinced that I would choose to use it if I had the choice; not just for my own personal projects but for large scale applications where the codebase is shared with many developers.

I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing and if we could bless JavaScript with a built-in and robust typing system then I don't think many people would be against that. My issue is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value.

i) Like a framework, you are at the whim of TS devs as it gets updated (edited)

For example, a new package you install can require a new TypesScript version. Once installed, you then may need to update your source code. This can place quite a high tax on the developer, where perhaps a 10 minute change becomes hours long.

ii) Libraries are badly documented

Most libraries do not document their types, or have no examples using TypeScript. Some worst offenders: Apollo, Protobufjs. The type definitions exported by these libraries can be large and complex, and the error messages emitted by TypeScript are so long and cryptic the result is often a drawn out process of trial and error along with trawling through source files.

iii) Error messages are hard to follow

Errors are long and don't provide enough detail. They will explain a type mismatch referencing many types you may not have ever seen, and are not documented anywhere. Except for simple errors, many of them are very hard to follow to a remedy.

iv) It requires yet more transpilation

Transpilation takes time, and always adds a burden to developers. I didn't mind so much with ES6 etc because eventually many functions were included in a broad set of browsers. There doesn't seem to be much progress including TypeScript in a browser, and feels like these complicated transpilation steps could be with us for a long time.

I could probably add more to this list, but my point is that I just can't see that TypeScript is worth all this time investment and making progress so slow sometimes. Are there others that come to this conclusion? I mainly see positive posts about TypeScript.

edit: I referred to TypeScript as a framework which it isn't. However it feels similar to me in that you are at the whim of TypeScript developers and how they decide to progress with the language.

468 comments

[ 2.8 ms ] story [ 366 ms ] thread
Of course, there's more than one way to build a good product.

Personally speaking, I'd say that adding another layer of abstraction onto your stack shouldn't be a dogmatic thing that you just reflexively do without considering the actual needs of a particular project. TypeScript offers some benefits for certain types of complex projects, but also some costs and problems that might not be worth dealing with for certain projects.

It's a little bit like GraphQL in a sense. That's a phenomenal idea...for a product like Facebook...but probably not actually needed for every single project.

Could you describe the costs and problems that might be considered not worth dealing with?
> I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing and if we could bless JavaScript with a built-in and robust typing system then I don't think many people would be against that. My issue is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value.

If I take your question prima facie, then yes it's still worth it, since you seem to be dismissing the main reasons people use TypeScript, the static type benefits, and the bulk of your arguments seem to actually be about how TS can improve, not why one should throw out TS wholesale, which I personally would never do.

In other words, you're focusing on the 20% BS out of the 80% benefits. Can the 20% be improved? Of course, but I'll take 80% benefits over 0% with JS any day.

Doesn't your counter-argument beg the question whether it is indeed 20% BS vs. 80% value? I think the OP is asking about pretty much that percentage. Personally I feel it's more like 70% BS vs. 30% value. Types, after all, are a very weak ontology, i.e., you still cannot know for sure that just because your code compiles it interprets the values it's getting from other party's code correctly. I would even argue that it may create a false sense of safety -- just think of the Mars satellite that crashed because some developer thought a number was in imperial units when, of course, it was in SI.
> Types, after all, are a very weak ontology, i.e., you still cannot know for sure that just because your code compiles it interprets the values it's getting from other party's code correctly.

This again seems to be throwing the baby out with the bath water. Just because in some cases types can't be verified does not mean we should fully be without types at all. There are a myriad of ways to mitigate even this, Parse, Don't Validate comes to mind [0]. Type Driven Development is another way [1], as well as using runtime type checkers like Zod. This article by Kent C Dodds is a really good example of the latter, it covers everything you're talking about regarding unknown types [2].

> I would even argue that it may create a false sense of safety -- just think of the Mars satellite that crashed because some developer thought a number was in imperial units when, of course, it was in SI.

Actually, that sounds to me like just the opposite case. The dev thought it was in imperial units because they might not have known the type of said number. If the number was instead typed with `ImperialUnit unit = ...`, that issue might not have occurred. Now, if the unit value was inputted incorrectly by the programmer, that's a different issue, no amount of typing will fix a business logic typo. As well, if the satellite was fully untyped, issues like these would have occurred far more often, so taking a singular example as a damnation of an entire paradigm doesn't really work.

[0] https://news.ycombinator.com/item?id=27639890

[1] https://blog.ploeh.dk/2015/08/10/type-driven-development/

[2] https://www.epicweb.dev/fully-typed-web-apps

You need to parse and/or validate any external input before you declare that a variable or field is a certain type, as you probably should be doing without Typescript anyway. Being strict in what you accept and ensuring that you're not lying to the type checker solves the vast majority of these types of issues.

It's been a few years since I worked with TS professionally, but at least at the time, I saw it as 95% value, 5% BS. It provides such plainly obvious value in my eyes that I've decided I'll never write JS again unless it's a single file script or a small throwaway project/PoC.

In my experience, even the one file scripts eventually get converted to Typescript when I realize I cannot specify my types :)
Types help prevent a narrow class of errors. They also help with refactoring. They help avoid messy checks getting in the middle of your business logic. All of this is more than enough to justify using them.

Types do not replace other checks and tests.

I don't think the Mars satellite crashed because they trusted the type system.

Come on, the OP literally said:

> I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing

The OP is interesting in talking about how much of a pain in the ass TS tooling is, and... it's fair to say it's annoying.

If you accept that static types are good (and the OP explicitly said they do), then what are going to do? Basically the OP is saying, "I want static types but not the TSC compiler or ecosystem"; well... it sucks, but you're never going to get that.

The comment you're replying to is just saying: "Well, if you want static types, you gotta live with the bad stuff".

> Doesn't your counter-argument beg the question whether it is indeed 20% BS vs. 80% value?

Nope.

Let me clarify - I pretty much agree with what the parent says - "it's more like 70% BS vs. 30% value".

I do still want that value i.e. static typing, but as you point out I can't get that without the BS. And so I would rather have no typing which is the only other option (except using a different language).

> And so I would rather have no typing which is the only other option (except using a different language).

This part is what is so wild to me. I simply cannot imagine throwing the baby out with the bathwater, so to speak, to throw out the entirety of static typing just because of the BS around it. In my experience, static typing is superlative, it would have to be some extremely rare situation for me to give it up.

I spent 6 years programming production JS delivered to millions of people before I went to TS and it just wasn't that bad. The code was clean, and the team didn't ship many bugs - this was for a big frontend and ~12 microservices.

Webpack added a lot of overhead - but if you know what came before it, it was a godsend. React added a super complex library, vs Backbone which was only a few hundred lines of code but React is totally worth it.

I'm not just trying to hark back to "the good old days", I think the ecosystem is a big improvement from where it came from but I just haven't seen enough benefit from TS for all the work you need to put in.

We have that in the form of ReScript.
I like TS for the completions and the documentation. I know OP was complaining lack of documentation but knowing what properties a giant object takes, even if those props don't have doc-comments, is still wonderful.

What I've been doing is, whenever I'm handed a random JSON blob, I throw it into a JSON->TS interface converter, paste that back into my project, and I never have to question what the heck the server is returning to me again.

> In other words, you're focusing on the 20% BS out of the 80% benefits. Can the 20% be improved? Of course, but I'll take 80% benefits over 0% with JS any day.

There are other alternatives outside typescript and javascript, especially for serverside development.

Serverside, sure, I'll agree with you there (I use Rust for my backends).

Clientside, I've tried a lot of compile-to-JS or WASM languages and frameworks. They're just not there yet, especially when you run into some compatibility problems, not to even mention library support on the frontend. The reason I like TS for frontend is it's just JS at the end of the day, you can strip out all of the types and it works. Therefore, things like compatibility issues are simply...nonexistent.

I won't defend TypeScript. Mainly because I'm not interested in doing such a thing; I don't like it that much, clearly not enough to care.

But even so, I will say a couple of things about your arguments.

Regarding i), no, it's not a framework. But then again, I don't think that's what your argument expresses anyway. You seem to be saying "it's yet another dependency you need to keep up with". This would be correct and a valid argument. But it's unrelated with "being a framework" (which, again, it is not).

As for ii)... I'm afraid this argument could be valid for any large group you want to pick in software. Are you arguing JS libraries at large are better documented? Sounds highly dubious. From a different angle, is this a problem with the language itself or is it a problem with the libraries?

Finally, regarding iv), there is no "progress including TypeScript in a browser" and you should never have expected it. Not saying it will never happen because some person somewhere might do it, but you shouldn't expect it.

Regarding iv), I disagree that one should not expect this to happen. There's a stage 1 ES proposal for allowing TS-like syntax in the browser: https://github.com/tc39/proposal-type-annotations So there's good reason to believe this may actually happen in the next couple of years.
Everyone (including the authors of the Type Annotations proposal) seem to be on the same page that static typing - "including TypeScript in a browser" - is not desirable and will not happen.

For the avoidance of doubt, the Type Annotations proposal is not actually static typing, but just a 'fancy comments' for the JS interpreter to completely ignore.

> From a different angle, is this a problem with the language itself or is it a problem with the libraries?

It's a problem for me - the developer. From my viewpoint I don't really care where the responsibility of bad documentation lies, only that it makes me not want to use TypeScript.

> Are you arguing JS libraries at large are better documented? Sounds highly dubious.

You can't really decouple JS libraries from TS. Most JS libraries still maintained support TS these days. My point is that many of them are still documented using JS with JS examples, and don't fully document the types that go along with all their methods.

> You can't really decouple JS libraries from TS. Most JS libraries still maintained support TS these days. My point is that many of them are still documented using JS with JS examples, and don't fully document the types that go along with all their methods.

Ok, but... what you're saying here is that, while you're not convinced by TS yourself, you expect all JS library creators to be convinced. Why should they be?

I am not saying I expect them to be better documented, only that the reality is that they are not well documented in TS and that makes TS difficult to use.
> It's a framework, with all the usual framework downsides

> For example, a new package you install can require a new TypesScript version. Once installed, you then may need to update your source code. This can place quite a high tax on the developer, where perhaps a 10 minute change becomes hours long.

No. It's a language compiler. You can upgrade it safely without changing a single line in your codebase. If there is a breaking change (sometimes, regarding the strictness) there's also a configuration option that lets you keep the previous behavior.

> ii) Libraries are badly documented

And so you're going to lose any and all typing as your solution? I don't understand. Undocumented but typed >>> undocumented and untyped.

> iii) Error messages are hard to follow

I disagree completely, TypeScript has helped me many times to understand what's happening and why - I mean errors that I wasn't aware of in my previously untyped JS codebase.

> iv) It requires yet more transpilation

> Transpilation takes time, and always adds a burden to developers.

Doesn't matter. Use SWC or esbuild for sub-100ms compilation times. Your CI is a long running job due to tests and lint anyways. Nobody is writing pure uncompiled JS these days - you can't use NPM libraries that way, so there's always some (Web)pack step. I haven't seen a single developer who liked having to care about browser versions and wants to go back to that - but if you add a compilation step you get that for free and can write the latest and greatest.

I agree with your comment, however please don't make new accounts just to respond to a single post or comment, judging by your username.
> No. It's a language compiler. You can upgrade it safely without changing a single line in your codebase. If there is a breaking change (sometimes, regarding the strictness) there's also a configuration option that lets you keep the previous behavior.

I am currently stuck on a very difficult issue because of a TypeScript upgrade. The upgrade caused a type mismatch with a dependency that wasn't previously an issue, and due to the lack of documentation on that dependency I am currently trawling through source code.

> And so you're going to lose any and all typing as your solution? I don't understand. Undocumented but typed >>> undocumented and untyped.

No documentation of types means going into source code to see what is there. Sometimes there could be multiple types that could be used for something, and it's not clear which should be used. Most libraries have clear docs to show me how to use a function, I'll take that any day over the uncertainty of which type may be correct in many places in my codebase.

> Doesn't matter. Use SWC or esbuild for sub-100ms compilation times. Your CI is a long running job due to tests and lint anyways. Nobody is writing pure uncompiled JS these days - you can't use NPM libraries that way, so there's always some (Web)pack step. I haven't seen a single developer who liked having to care about browser versions and wants to go back to that - but if you add a compilation step you get that for free and can write the latest and greatest.

Not arguing for no transpilation though browser compatibility isn't much of an issue these days unless you are using some super new features of the language (the reason is more about bundling the code together and jsx as far as I understand). I am arguing that each transpilation step adds yet more config that needs to be built, understood and maintained. TypeScript is probably the worst offender, almost as much work as maintaining another webpack config in your projects.

Did you upgrade Typescript (and if so, why), or did you upgrade some project dependencies, or type definitions?

> No documentation of types means going into source code to see what is there. Sometimes there could be multiple types that could be used for something, and it's not clear which should be used.

I haven't had this experience, and I'm not super experienced with Typescript. Are you using VS Code? It typically makes it trivial to find the definitions of things I'm interacting with in the editor.

> Did you upgrade Typescript (and if so, why),

What an odd question! Even ignoring new features and better type inference that comes with new versions — once you add typescript to your project, it becomes one of its dependencies. Don't you regularly update your dependencies, just as a good practice, not to let your codebase slowly rot?

> Don't you regularly update your dependencies

No. Update dependencies as needed for security patches (which typically avoid breaking changes), other than that never update unless there is an explicit business need.

I am the opposite. To me, dependencies in a project are a debt to which I regularly make my payments by keeping them up-to-date and resolving breaking changes as they arise. Allowing dependencies to fall too far out of date, in my experience, made updates — when they became necessary — too painful.
Yeah, I'm with you. I have a lot on my plate, maintaining and developing the main application I work on single-handedly, while also working on several other projects, and putting out fires elsewhere in the company as needed.

I don't have time to spend days to weeks figuring out why upgrading Tailwind to version 3 breaks the project because of (presumably) my version of create-react-app.. do I need to eject, or copy the .ts/.tsx files over to a Vite project? Do i want to fuck around with CRACO, or editing the internal monster of a webpack config file directly?

Yes, critical security updates are important, but you shouldn't just go around upgrading major versions of other packages in your production app, without the understanding that it might be an incredibly time-consuming endeavour.

> Did you upgrade Typescript (and if so, why), or did you upgrade some project dependencies, or type definitions?

I need to upgrade it because I upgraded a dependency that needed a newer version of TypeScript to compile! And I needed that dependency to be upgraded to use a newer version of NodeJS.

It seems that the newer version of TS was more strict, and now I can't find a type from ProtobufJS that fits the code. I can update here when I understand more about this particular case, but presently my best bet is to loose some typing and autocompleting by using some unknown types :(

Did you try regenerating protobufjs and .d.ts files after upgrading?

For me it's something like

    npx pbjs -t static-module -o protos.js *.proto
    npx pbts -o protos.d.ts protos.js
No. It doesn't fix any of the problems with JS and it introduces a lot of new ones, namely static types. Also just way more typing, but I suppose that's literally in the name..
I don't have a lot to add except that my experience with it has been very positive; your complaints are mostly valid, but for me those pain points disappear in the shadow of all the things I no longer have to spend time stressing about or debugging
So much this.

If you’re learning JavaScript or any components of the language, you’re better off just starting with typescript (given the technical acumen up front).

It’s absolutely a no brainer, long term roi. If presented the opportunity to integrate or use now vs later.

The community is also very active, and it’s under Microsoft - and has been well maintained and quite active. Lots of libraries.

> you’re better off just starting with typescript

It depends. The tooling is still a barrier (even though it's gotten smaller); the cost is small for a real project, but for someone who's learning and knows nothing about the ecosystem, it could be a real obstacle to dive all the way in at once. The exception would be if you're starting with something like Deno that integrates TypeScript seamlessly. Outside of that, tools like esbuild have significantly lowered the bar vs a few years ago when you had no choice but to configure webpack + babel. But even esbuild isn't quite zero-configuration

If you're just starting off with JS or TS you shouldn't be messing with tooling at all. Just install one of the many create-react-app derivatives, run one command and start developing. All those boilerplate generators support TypeScript now, too, so you don't even need to do anything extra to start using TypeScript. Even TypeScript itself can be incrementally adopted since it's a superset of JS.

You will outgrow those app generators, but for a learning project? There is no need for you to even see a webpack file.

As humans it is easy to forget the time savings that we don't see. For a project that uses a lot of Type annotations, it is like getting a bunch of unit tests for free or writing a bunch of boilerplate code to validate inputs.
Yeah it feels like the Seinfeld Effect here. TS is so pervasive now that its vast upsides are just "the new normal", taken for granted.
I worked for many years without TypeScript, and the development flow was a lot more pleasurable without a big difference in the number of bugs I saw us shipping.
I work on a ruby code base that has extremely good test coverage, something around 20,000 unit tests for a relatively simple app, and it’s still almost impossible to update ruby or rails without breaking something. The thing that broke is always impossible to predict from reading the release notes.

The most infuriating thing is it’s almost always something a typed language would have picked up like a functions parameters changed or things removed.

No amount of unit testing or browser automation is a sufficient replacement to type checking.

If you write a project for yourself, or develop a startup or an MVP it's often not worth it.

Late-binding dynamically typed languages are underrated, if you can hold the mental picture of types in tour working memory, that is.

It's lipstick on a pig, and yet another layer of complexity on top of the myriad of modern web development.

The solution to better web development is staying as far away from JavaScript as possible, not polishing what is frankly a turd.

I think it's masochism to have a Javascript project that big that benefits from strict typing.

I don't like Typescript. I just like it more than Javascript.
i) TS isn't a framework. And you don't have to use it everywhere in your system. You can decide how heavily to leverage it, developing a 'core' TS subset that powers a broader JS layer (or the opposite, or something different)

ii) Lots of libraries are extremely well documented and typed. This is the same in any language not just for types but also for docs, capability, perf etc. This argument applies to all software everywhere so it doesn't make sense to single out TS

iii) Error messages can sometimes be hard to follow. But you get better at parsing them very quickly when they get gnarly.

iv) Transpilation is nearly always a required step anyway. Adding TS support is minimal. There are plenty of tools that do TS to JS on an order of magnitude of MS.

All decisions are tradeoffs.

What benefits does it bring (ignoring the biggest one of them all)?

TS makes it easier to maintain software across large teams by providing a mechanism to express relationships in a codebase.

They are self documenting and replace a lot of JSDoc needs (letting you focus docs on more useful info like intent, design choices, example usage, etc).

Types can also replace the majority of unit tests validating code is correct saving time on running fewer unit tests and letting devs focus on integration tests.

Lastly, I've never seen or experienced something breaking from upgrading the Typescript version in a project. Even when a TS upgrade has 'breaking changes' they never actually break anything in practice that I've seen.

> ii) Lots of libraries are extremely well documented and typed. This is the same in any language not just for types but also for docs, capability, perf etc. This argument applies to all software everywhere so it doesn't make sense to single out TS

I am singling out TS because although most good libraries have documentation for all of their methods, along with examples, many useful and popular libraries do not include full documentation of their types. Some hardly any at all.

Usage examples are some of the most useful piece of documentation you can have in a library, but many authors choose to show their examples in JS, in order not to be too opinionated. It is the fact that TS is not actually part of the language, and simply an add on, that I believe is the cause of many of these issues.

> What benefits does it bring (ignoring the biggest one of them all)?

I do believe it brings benefits and agree with what you have written, of course my view is that those benefits just aren't worth the effort. In my experience some of the best codebases I interacted with were neatly written and well documented JavaScript codebases - no TypeScript, whereas many of the TypeScript codebases have been very hard to understand and work with. This is by no means due to TypeScript, however it doesn't make me think that it helps in terms of making anything that much better.

I can't even remember many times TypeScript has actually prevented a bug, it's been more useful for documentation. But then I would prefer JSDoc which isn't so difficult to maintain and can still provide autocompletion for you.

> many useful and popular libraries do not include full documentation of their types

> but many authors choose to show their examples in JS, in order not to be too opinionated

This is certainly true sometimes, but I don't see why it's a reason against using TypeScript? If you're calling a TypeScript API, the way you use it should look basically the same as the way you'd use it in JavaScript. You usually don't have to do anything special with the library's types unless you're getting fancy

There are exceptions- I've had a rough time fighting to get code using the styled-components library to fully typecheck, because that library gets super fancy with the way they represent things (I don't like it for that reason personally, but I know others do). But libraries like that are the exception in my experience, and if it's really that big of a drain on productivity, you can always bail out and use `any` types to skip dealing with it

I am thinking of the case where you are passing an object or class to an API that needs to be shaped a certain way. In this case you need to know which type to import/use to pass it through.

For many simple libraries it's not too much of an issue, but for more complex things like Apollo (which also doesn't include much TS in their docs) it's a lot of hit and miss until you get it right.

Sure, that can happen. I guess I feel like if it's that much of a problem for any given library, you always have various ways of disabling checks where you need to and still benefiting from them elsewhere. So it's still a net benefit

I will also say- GraphQL almost by nature is gonna be a really hairy thing to statically type, especially on the server side. We've got an Apollo server at my company and thus far we've pretty much just punted on trying to type that part of things. Which is also more okay than might be for other things, because GQL does its own runtime validation anyway

If you are doing JS then you should certainly be using Typescript.

The best choice however is to simply use a better ecosystem entirely.

IMO JVM+Kotlin is great general purpose combo, Rust is good if you don't write the sort of code that needs GC'd structures, etc. Between those two I rarely need to consider anything else.

The answer to "is {{tool}} worth it" is almost always "sometimes"

Typescript is a wonderful tool for many situations. Typescript may not be needed for all situations. There's upfront cost to configuration and tooling. But you get type safety and automatic documentation.

In all my new non-trivial projects, I default to typescript. It has caught so many issues and saved me a lot of time. Not having it feels like driving without a rear-view mirror. But, if I'm just writing a little script, I might omit it.

I find TypeScript very helpful! As a self taught developer I always used to just use JavaScript, but after joining a big company and working with TypeScript I prefer it now. I like how I always know "what's in the box" now when working with different objects and whatnot.
I think you need to be very careful there. Only because something is, e.g., a number, does not mean you know what it represents. I think Typescript might actually create a false sense of safety.
I'd say for most people, beyond small scripts/cli/micro-microservices, the ceremony of setup/environment overhead for it is worth it, and continually pays dividends. You can usually copy-paste a common config file around to bootstrap.

Most of your (pretty good actually) critique are points to make the least-bad way of doing JavaScript even better, and I'd agree could be improved.

Others have taken notice.

"Native support" of TypeScript is done by Deno. And tight TypeScript (and other adjacent tooling) integrations with VS Code and WebStorm.

And transpilation is being worked on by various builders. Stripping types and running through esbuild or swc is fast. For typechecking part, was a proposal to have TypeScript be rewritten in Rust for performance.

We can lament that JavaScript went from being a web document enhancer to being shoehorned into a full application compilation toolchain, but the old Jquery thru Expressjs era of doing things has significant drawbacks for full sized applications/APIs/etc.

I haven't found much agreement, or at least to the extent I believe it, that Javascript and HTML and CSS have all been shoehorned and built upon completely beyond their original specs.
Those sound like the least controversial opinions ever.

What's nice is that despite looking ugly, those shoe horns have done a pretty good job, and they all make effective tools for building useful stuff, and that stuff can be built by people who aren't very good at building stuff.

It's very much a success story that so much html/css/JavaScript is a garbage fire. They're really effective tools, up there with excel

(comment deleted)
I'm with others (it's worth it when there are more people / the code needs to be correct), but the example of Protobufjs is unfair: I expect it to be super complicated to work well with Typescript. TRPC is growing for a good reason.
The whole shtick (and beauty) of Javascript is that it is a dynamic language. In some point in time corporate Java people started using JS, and now we have this : "is well understood that static typing is a good thing". It's not. But as always you have a vocal minority, influencers and evangelists shouting their BS, about how TypeScript has terraformed theirs lives and they can't imagine life without it.

Use your head, if you don't like TS, don't use it.

I'd argue that the shtick of javascript is that it runs in a browser. The dynamic thing seems like more of a coincidence to me.
Id argue the static typing is great, and the best part of Java that is otherwise ruined by OOP. Give me the types and leave out all the OOP factory garbage, and you are left with the best parts. That’s what typescript ends up being.
Typescript is significantly better than java imo, in that it can figure out what the right object shape is on its own for the most part, rather than needing to write another file for every intermediate data object in a process flow

    I want to skip over the static typing benefits argument, because I think it
    is well understood that static typing is a good thing and if we could bless
    JavaScript with a built-in and robust typing system then I don't think many
    people would be against that.
Well, yes. That's what Typescript is. If a built-in and robust typing system were added to Javascript, it would be the same thing as integrating Typescript into the ECMA spec. for Javascript.

EDIT (some more thoughts):

    For example, a new package you install can require a new TypesScript
    version. Once installed, you then may need to update your source code. This
    can place quite a high tax on the developer, where perhaps a 10 minute
    change becomes hours long.
Yes, that's not very different than upgrading to a new version of e.g. Python or Ruby on the back end. The problem is that you're seeing Typescript as "just a framework", rather than a compiler/interpreter. If you view upgrading Typescript versions the same as e.g. upgrading Python or Ruby versions, and plan for it accordingly, then you'll at least have the correct expectations regarding the scope of work, even if the actual work to do isn't any less.

    Most libraries do not document their types, or have no examples using
    TypeScript.
If a type system were integrated into Javascript itself, it would have to be optional, in order to maintain backwards compatibility with the vast untold billions of lines of Javascript that are out there. Thus, you'd have exactly the same problem. It's very difficult to add a typesystem to a language after the fact.

    Errors are long and don't provide enough detail. They will explain a type
    mismatch referencing many types you may not have ever seen, and are not
    documented anywhere. Except for simple errors, many of them are very hard to
    follow to a remedy.
Poor error messages are an issue with any type system that allows generics. Typescript's error messages are, at least in my experience, better than C++'s error messages. I find this remarkable, given that C++ was designed as a typed language from the beginning, and Typescript has, as one of its design constraints, strict backwards compatibility with Javascript.

    I referred to TypeScript as a framework which it isn't. However it feels
    similar to me in that you are at the whim of TypeScript developers and how
    they decide to progress with the language.
That's true of any programming language, Javascript included. If you're writing Java, you're at the whim of Oracle. If you're writing C#, you're at the whim of Microsoft. If you're writing C++, you're at the whim of the C++ standards committee. If you're writing Python, you're at the whim of the Python Steering Council (and you used to be at the whim of Guido Van Rossum). Every programming language has some person or committee that's in charge of it, and if you're choosing to use that language, you're implicitly accepting the decisions made by that person or committee.
The question of whether it's "worth it" really boils down to you and your specific requirements.

Even within the same project, there are times when I don't want typechecking - when I am prototyping something out and want to move fast.

And there are other times, when I want typechecking - when I am finalizing a feature implementation or doing integration with existing logic etc.

It's not a framework. It definitely is a language in its own right.

But from personal experience, the group productivity goes way up with larger codebases with many ICs working on it. Unit tests become type checks. It opens up a lot of extra bandwidth for more sophisticated functionality or better tests.

Solo IC, working on a small project, with no intention of ever writing tests - you might see TS be an overhead.

To sum up, your requirements decide whether it's worth it.

I have seen this IC vs team aspect discussion before, and it definitely has merit. However I am starting to question if it's even worth it for larger codebases used by many devs, which is why I wanted to pose this question.

Can you think of cases where it's actually prevented a bug where that piece of code is unit tested? I have been actively monitoring for this to happen, but so far not seen it (I think I have seen it catch a couple of bugs for code that did not have unit tests).

Unit tests only trace one path at a time; static types cover huge possibility-spaces at once. But of course there are things they can't reason about, which is why we still test, but each of the two is better for catching different kinds of things. One isn't sufficient to replace the other.
A unit test can succeed while being completely wrong.

Eg. You test code that calls a dependency that returns a bool, but your tests assume an object response

Unit tests imply assumptions about the integrations, whereas types specify those asumptions

Types let you limit the size of the input space - JS lets you go ahead with (foo, bar) where they could be literally anything and you have to handle every edge case to test that (and I bet if you fuzz you'd find stuff) your unit tests don't handle. With a typed language I can specify the input space and know with certainty anything that calls that function (and compiles) is going to be within that space. This lets you dramatically reduce the complexity of your app, tests, and stress of refactoring!

Fwiw I'm an SDET and I regularly find bugs, on a daily basis, in a startup of around 40 people with a Python/JS web stack that TypeScript would have caught (and am pushing towards moving over to it).

Solo ic on a small project, you don't write tests? That's the easiest time to write tests! You don't have all the complicated context set up or writing test data, and saves you the run/debug loop for setting up specific situations.

My childhood not knowing about tests had a ton of wasted time trying to check that a change worked

My use case is a bit odd, but I've been using it for small personal web projects — so small that no dependencies are being pulled in and bare tsc is being used in place of a bundler — and as someone who doesn't have all of the ins/outs and do's/don'ts of JavaScript committed to memory (the vast majority of code I write is Swift or Kotlin) it's wonderful to have something catching errors before I save and reload the browser window as well as preventing "silent" bugs JS is notorious for.
Same here, I've found it very useful in projects where I don't have a lot of dependencies.

In another project with more exotic dependencies, it has become a hassle somewhat. I've found learning the .d.ts syntax to help easily get out of a situation, but it was a learning curve I still run into sometimes.

I find that I just make the .d.ts files any types

I could document types for that module, but I don't, and instead assume types as the output of code I have that interacts with them

I do that sometimes too. Sometimes I type the couple things I need out of a module. If it's something I end up relying on more, I usually start digging deeper and end up cloning it. The hardest are the large libraries with no types and no DefinitelyTyped types. Also monorepos can be annoying, when the main package is typed but the individual packages aren't, if you have to start poking at things deeper.

You do get a lot of escape hatches for different outcomes though, dependant on amount of desired effort

I add more thorough types for dependencies than for my own code, specifically so I don’t oops myself on other people’s code I’m less familiar with.
Although this seems to be the opposite sentiment to what many are saying which is that it's more useful in larger projects, with many contributors, I think I probably understand this side more.

Dependencies are where it starts to get tricky. It also gets tough when someone else has configured TypeScript, or you need to add some complex config. I would still opt out for smaller projects because they don't quite benefit so much from TypeScript, and eventually I would expect to run into something that would eat at hours of my time for a simple change.

Offtopic perhaps, but if most of your code is in Swift or Kotlin, have you tried the new Kotlin frontend support? I don't have any project where I can use Kotlin in the backend right now but I've always wanted to give the Kotlin frontend a go as an alternative to TypeScript.
I haven't, mostly because none of my front end web projects feel large/complex enough to justify the extra overhead (probably wouldn't even be using TypeScript if it were any more involved than running `tsc --watch` in a terminal window). Might look into it for future projects though.
I pretty much deplore using Typescript for fast paced UI development.

I will be using vanilla Javascript in my own projects for the foreseeable future.

It's got its advantages, but they had an opportunity to solve one of JS's biggest weaknesses—the terrible standard library. And they just... didn't.
I'd like to hear from anyone who has issues with typescript as a build tool, either via `tsc` or an integration via something like `rollup`, what issues are you having? How often?

I have not found, even in really large projects with thousands of files, that its been an impediment to anything.

My general disposition is the whole "anti build tools" moment is a bit overblown in practice, and I'm always searching for valid counter evidence of persistent issues that can't be easily overcome.

I agree on the "error messages are hard to follow". A lot of times when you have an error it doesn't clearly communicate "hey it should look like this" (something Rust does soooo well) and instead says something like "types or property A incompatible with property B that is incompatible with X and not Y and ....". It basically just explains the nesting but is so hard to actually make sense of or how to solve it.
Something that might help is creating typed / untyped boundaries. Wrap a (possibly untyped) library with your own (maybe incomplete) typed wrapper. Then let Typescript check everything up to your particular boundary and ignore everything afterwards.

It's on you to make sure you're not misusing stuff at the boundary, but less hassle to get set up and always something you can clean up later.