I'm heavily biased towards small teams and small to medium programs though. I can at least imagine how TS improves ad-hoc documentation in some cases, which can definitely help in the "maintaining the code over a long period by different people"-scenarios.
Being able to specify interfaces is absolutely nice, but overall I'm not convinced it's worth the trouble.
Judging by the seismic shift in the industry away from vanilla JS towards TS I'd say that qualifies as an extraordinary claim.
It would be interesting to hear some of the details behind your experience.
Most of the functional errors will be caught either by unit tests or by functionality noticeably not working. These are not things that would be caught by Typescript anyway.
The irony is that we're using typescript in the front-end, where it mostly gets in the way. I think Typescript would have been more useful in the backend, but we're not using it there, because originally our backend was trivially simple. Now that the backend is becoming bigger, I can imagine Typescript would be more useful there.
It could be that Typescript doesn't work well with our version of Vue. (I think the latest version is designed around Typescript which will hopefully make the process a lot easier.)
In my experience working with React, which is pretty heavily invested in typescript these days, if you go reasonably deep on doing typescript interfaces, it's like a switch gets flipped.
A light dusting of typescript really does barely anything; it's just boilerplate. But once you get up to about 80-90% coverage, it's like a switch gets flipped. All of a sudden it's really, really good at detecting discrepancies - I had a thing I was working on today, where I had a cute little svg icon component in the giant SPA program we're writing - I was just reusing the thing, and attaching a click handler to it, and all of a sudden - this component we hadn't touched in months, typescript starts griping about it. And I'm like "oh come on, this is so basic - what the hell could be wrong about passing in a simple onclick handler?" Well - turns out nobody had ever needed to use the "event" param on that function, so it didn't even use one internally - what I was passing in, in plain JS, would have just been thrown away, because the internal 'passthrough' version of the function had no parameter at all. And I didn't notice it in light testing (we have TS set to emit our program even if it's failing tests). I tested the component, and because the behavior's invisible/internal, it seemed like it was probably fine. Maybe I would have caught it with really earnest, aggressive testing later, but I didn't even need to - typescript just nailed it instantly.
I've had the privilege of working on some game development stuff outside of a web stack, and holy smokes does working in a complete, algebraically typed language change everything. When you go from 80-90% type coverage, to "hard 100%", it's just a complete 180°. It's just _freaky_ how good it is at catching errors. I'll change one little thing, and it can tell me "oh yeah - you know that cutscene an hour into the game? Yeah, you broke that." It's uncanny. It just absolutely changes everything about how I work.
Basically, any use of `any` should be avoided. Once you tolerate one `any`, you're on the way down.
One thing that I really, really do like about typescript is that you need to be explicit about whether a value can be null. Java lacks that, but the difference between `foo: string` and `foo: string|null` is stark.
Otherwise I dunno what this could be. Especially what TS could be disallowing that'd be all of: valid in JS, a good idea in JS, and especially time-consuming to fix.
I honestly wanted to believe in the value of Typescript and was enthusiastic about the switch, but it really hasn't proven itself over the past year.