TypeScript. The tool that promises to catch your bugs before they sneak into production. It’s been hailed as a game-changer for developers, but let’s face it: not everyone is on the TypeScript train. And that’s okay.
Is TypeScript really the golden ticket to better code, or is it just an overhyped tool adding unnecessary complexity? Let’s see.
Why Some Developers Think TypeScript Is Overrated
- It’s Verbose—Sometimes Painfully So TypeScript can turn a few lines of JavaScript into a sprawling mess of declarations. For small projects or quick prototypes, all the extra typing (pun intended) can feel like overkill.
Example:
A simple function in JavaScript:
function add(a, b) {
return a + b;
}
The TypeScript version:
function add(a: number, b: number): number {
return a + b;
}
Multiply this verbosity across hundreds of functions, and you start questioning if it’s worth it.
2. It Slows You Down (At Least Initially)
Learning TypeScript takes time. Even seasoned developers often wrestle with configuring types, setting up the environment, or dealing with cryptic error messages. And for teams that aren’t well-versed in TypeScript, onboarding can be a significant hurdle.
3. False Sense of Security
Yes, TypeScript catches type errors, but it doesn’t guarantee bug-free code. Logic errors? Still on you. Improper API usage? TypeScript can’t always save you. Sometimes, the promise of “safer code” makes developers overly reliant on the tool instead of focusing on writing clean, maintainable code.
4. Not Always the Right Fit
For small-scale projects, TypeScript can feel like bringing a bazooka to a water balloon fight. The setup and maintenance don’t always justify the benefits when your project is a simple script or a one-off tool.
Why TypeScript Is Loved (And Sometimes Deserves the Hype)
1. Catch Errors Early
TypeScript shines in large, complex codebases where bugs can hide in plain sight. By enforcing types, it reduces runtime errors and makes refactoring less nerve-wracking.
Example:
Imagine a function expecting a number
, but someone passes a string
because of a miscommunication. TypeScript will scream at you before it becomes a production nightmare.
2. Improved Developer Experience
With TypeScript, your editor becomes smarter. Autocomplete, inline type hints, and better documentation make navigating large codebases a breeze. It’s like having a co-pilot who actually knows what they’re doing.
3. Scaling Teams
In large teams, TypeScript acts as a safety net. It enforces a shared understanding of data structures and function signatures, making collaboration smoother.
Scenario:
You’re working with five other developers across time zones. Instead of guessing what a function is supposed to do, TypeScript gives you a contract to follow.
4. The Ecosystem Has Evolved
Many libraries and frameworks now ship with TypeScript definitions, meaning you don’t have to do the heavy lifting. Angular, Next.js, and even React support TypeScript out of the box, making integration much easier.
When to Use TypeScript (and When to Skip It)
Use TypeScript:
- Large, complex projects with multiple contributors.
- Codebases that need long-term maintenance.
- Projects where type safety can significantly reduce runtime errors (e.g., APIs, enterprise software).
Skip TypeScript:
- Quick prototypes or experimental projects.
- Small teams or solo developers without prior TypeScript experience.
- Simple scripts or utilities where the overhead isn’t worth it.
So, Is TypeScript Overrated?
It depends on who you ask. To some, TypeScript is a lifesaver, making large projects manageable and reducing errors. To others, it’s an unnecessary layer of complexity, especially when working on smaller projects.
The key is to treat TypeScript as a tool, not a religion. Use it where it adds value and skip it where it doesn’t. And remember, no tool is perfect—not even TypeScript.
What’s your take? Love it? Hate it? Somewhere in between? Let’s discuss in the comments
Top comments (43)
I wish there would be a strongly typed version of JavaScript. At least the damned numbers! I hated TypeScript even more than I hated flow, but adopted it for the reasons OP described.
I hate dealing with JS bundlers and compilers, so I use Deno for my side projects and push through with Vite and such elsewhere.
I’d say it’s a “love/hate” relationship for me because I need types (but hate writing them) and I love flexibility JavaScript gives me.
When I hear "I love the flexibility JavaScript gives me", I hear "I love that objects can be anything at any point of time in the code". Do you have a specific example of where JavaScript gives you flexibility whereas TypeScript does not?
Conceptually, TypeScript works by restricting variable types to certain types. Imagine types as circles where the type
any
encompasses everything, and within the any circle you have many other circles, for exmaplestring
,number
,Record
etc.. Within the string circle you have even smaller circles; string literals like"a"
or"red"
. Within theRecord
circle you haveRecord<string, number>
, etc.. Your data will always be some sort of type within the any circle, and almost always, you will know / want to restrict the variable to only be within the string circle, or only thestring
,number
andRecord
circle and so on... You can choose to ignore these types whenever you want "flexibility" (just useas any
oras <type you want it to be>
), but then you will almost guaranteed get a runtime error or a bug.In practice, TypeScript does not restrict your types. It's a static type checker, so you can transpile the code to javascript and ignore all typescript features if you want. TypeScript only gives you more information on what variables can be at certain points in the code. It does not enforce this, it just says "Hey, your variable might actually be this - you should handle that case or beware that it's not what you think it is".
Oh I agree with you! TypeScript is still JavaScript, I meant that I prefer JavaScript over other languages like Go or Rust even though they are strictly typed but less flexible.
What I like about Typescript compared to Rust at least, is that types only describe what the data is instead of enforcing it. This is very useful when you have optional types:
in Rust, you need to unwrap the optional type or pattern match on it, which is relatively verbose and it's not really intuitive why you are required to do this imo. Rust is a great language though, it just requires a good understanding of the language (which I don't have yet) to not be slowed down by it. Typescript has a lower learning curve (but can actually go quite far too).
Yeah exactly my sentiment! DevX of Rust is way less pleasant than JavaScript/TypeScript, but worth it in many cases. What I’d like to have is something in between: runtime type validation, strongly typed numbers/binary data and manual control over garbage collection. I think it’s possible to make, I’m just not sure if I can finish making it in one lifetime alone 😅
The return type specification is not needed here. The following yields the exact same result:
Perhaps it does, but part of the reason for adding types is to make it obvious what's going on, and in more complex functions I don't want to rely on reading the function or hoping the IDE figures it out. I want to see the signature right there in plain sight!
Agreed. I, very often add the return type as I write code to get Intellisense's help. Most of the time I don't clean it up, hehe.
You should still be getting the return type from the Intellisense if you've returned a value from the function. I agree that it's sometimes nice to have the return type in the signature though since it shows an error at the return statement if you try returning something else.
I think the scenario is that when I write a function I know what it's returning. If I edit it in the future maybe to call another function and return that one's result, I no longer have the visual hint about what I need to return. The signature is like a contract between the author and the compiler/interpreter.
Maybe another way to put it is that it's like using the placeholder text in an input field as a label. It's all good until you come to edit the form and you can no longer see what the field is that now contains "8.5". Sure, the form validation will pop off if you enter "potatoes" but I'd like to be able to read the label saying, "how many carrots do you want?"
I wish the ESLint "recommendations" were the TS standard with strong typing everywhere, and the return type is required, including specifying
void
.I like how TypeScript generally cuts development time by half compared to trying to struggle with JavaScript.
And if you're using VS Code with its amazing auto completion features provided through extensions, no one types out everything
You don't realize how painful it would be to Type returns on every little arrow function you write. Every .filter,.map,.includes would need return tapes declared.
You put an extra semi-column but yes, type inference is great
Good eye. Removed.
Is it verbose? Yes.
Is it strictly necessary to avoid havoc? Yes.
The sole fact of having the compiler and the type checker yelling at you while coding is pure gold. Without it, you can use millions of misnamed or simply undefined stuff or even slightly out of type variables in JS and only find out at runtime, or even never. Or maybe a user doing an edge case will find out.
The only real pain of TS is setting it up in Node.js. That is generally so bad that using a boilerplate religiously is your only option.
The strength of typescript is in the type inference. Because of type inference you don't have to (should not) provide specific typings for a lot of things:
Oh this is dangerous new hype I've seen among new developers coming from UI world
First - defining return type you explicitly state what is intended return so you don't accidentally add null, record and string where only boolean[] is expected
Second - it saves time for TS as it doesn't need to dig deep to compute return type
Seen sad and funny bugs laying around
Saves time to create code but loses time to review and maintain it
I don't come from UI world. Do you come from Java world? Java likes to make everything explicit.
Using inference in typescript doesn't make it slower or faster. tsc is still compiling every line of code.
I come from JavaScript world and seen people handling weird types just because some function that was supposed to return only e.g. number started to return something more instead of throw or handling the case
And people didn't have enough context to reason if advertised type is true or buggy
So I've would say being explicit what your code is supposed to return will help future you and fellow developers to use your code
I haven't done performance checks but I trust this article has a point
github.com/microsoft/TypeScript/wi...
If you can prove it wrong please suggest an update there 😅
Typescript will throw an error if your return type changes to something that is not supported by the code using that function, no explicit return type needed.
Also you should read articles that you reference, especially if those articles come with a warning at the very beginning to read carefully. A quote from said article:
Thanks for linking an article that agrees with me, saves me a lot of work. They also make a lot of other side notes on that topic that you should probably read/understand.
I disagree, because I think explicit readabilty counts more.
Explicit return types should not matter for the readability of your function. If it does, your function is not readable and you're trying to take a shortcut.
This reason I prefer the JSDoc, I also use for small POC app, because so much nicer : JSDoc vs. TS
Ah, JsDoc: The ungrateful parasite. The problem with it is that its data typing is limited.
Hmmm... until now I can't found a data definitions which can declare with TS but cannot with JSDoc. Please drop me a example.
That is true, sometimes the line brake position is tricky.
Even I can use any TS declaration to my JSDoc npm library as imput.
Exactly "TS declaration as input to JsDoc", but JsDoc cannot declare types and have them reused in places. So JsDoc is and seems that will always be dependant of TypeScript.
Nor, In JSDoc I can declare any types which can I declared in TS
Nope, as far as I can tell (I don't use JsDoc for typing, so maybe you know better). It is not a feature of JsDoc to be able import from some other JS file with types defined. The best, according to AI, is to use
@typedef
in a JS file, then export some unused variable. Then import from other files. AI says this makes the@typedef
available.Bottom line is: JsDoc can import d.ts, but cannot create d.ts.
At the end you have TS in JSDocs 😂
Why bother and not to use only TS?
On top even Node is moving towards running TS without compilation so soon JS will be hidden away from developer
imho JSDoc is near different syntax of TS. But the main difference between TS and JSDoc is: for using TS is need to be coding in TS not in JS, so your TS code cannot run without a proper setuped TS compiling. But the JSDoc is don't force to you to compile your code and give all development hint and help as TS does. So that is the main difference between JSDoc and TS.
node just will be hide TS compiling for developer. Imho a web developer need to have a strong JS knowledge, do not feel lost if need to write some code in devtools:console.
Check examples here
jsDoc vs TS
It smells to much like TS
So why to learn another syntax if TS solves everything and more wisely accepted
I once worked on a project where TypeScript was used so wrong that it in fact made development harder (wrong/misleading types so runtime objects differed from what TS was saying). It's a shame, because I really think that TypeScript used right is super helpful. It doesn't have to be verbose either. You only need to type the arguments that cannot be determined automatically. For example, in the example you provided you don't need to type the return type - it's automatically inferred and will show you the type. Some people argue that you can use jsdoc instead, but that's just even more verbose...
My take; Use only as much TypeScript as you are comfortable with - it's modular by design, so you can use as much or as little as you want - and only type function parameters, or external data responses. Almost never use
as
, and ESPECIALLY never useas any
. If you're usingas any
, you are basically saying "idc about this bug, let's pray it doesn't happen".as
is also dangerous because you're saying that the type is actually something else than what TS is saying. That only happens if 1. There's a bug in TS, 2. You have writtenas ...
somewhere else and it was actually wrong, or 3. You have received external data which cannot automatically be validated.as ...
My own experience has been that typescript makes JS very verbose and much less flexible.
I had learned to be a very disciplined JS developer and when you are, JS flows easily and is easy to understand and fix.
But, once you start working with other developers, the things can go downhill fast.
If those developers don't understand good JS discipline, then yes, the code goes bad places really fast.
Of course, if you add typescript to a team of developers who are not disciplined, then the code can get even worse. I've seen hacks and workarounds to try and get around the typescript typing issues and the crud that gets created from that is even worse than with plain old JavaScript. The one thing I can generally say about typescript is that the people who prefer it are usually people who like discipline in the code, so typescript tends to draw in devs who are generally better at discipline.
I still prefer straight JS on a team of disciplined devs the best. It is fast, straightforward and terse code, but still easily readable.
In those environments I usually will include jsdocs with the TS goodness so that the ide stays smarter about things. I mainly only use them on exports. If it were simple enough to just use typescript on the exports, I'd probably be happier to use it in general.
I agree with your sentiment that coding in JS and TS requires discipline. But I don't quite understand the argument for JS "JS is more flexible". When I hear "I love the flexibility JavaScript gives me", I hear "I love that objects can be anything at any point of time in the code". Do you have a specific example of where JavaScript gives you flexibility whereas TypeScript does not? And anyway, you decide how many type annotations you want to add in TS. You can have a .ts file with no TypeScript types if you want. I've elaborated more on exactly this on my comment to @valeriavg if you're interested.
And I especially don't get it when you say you use JSDoc to get the type safety, when you just said that you avoid typescript because of verbosity. Isn't JSDoc more verbose? Or is it perhaps that you just find the inline syntax less readable (which is a reasonable, subjective opinion I guess)?
Typescript is a tool. Like any tool it can be used wrong. People who agree with the cons listed have mismatched expectations or misunderstand what Typescript is for. The people who expect the language to fix all bugs or prevent them from writing bad code are severely misguided.
I would advocate for the use of Typescript in all of the skip scenarios. The setup and use only appears convoluted to the Typescript newbie.
One criticism I have:
"TypeScript can turn a few lines of JavaScript into a sprawling mess of declarations" is followed by a contrived example even though it's true. What you've shown with the number types is just point of Typescript. It's hard to come up with a good (bad) example but we'd all know it if we saw it.
For me, switching from JS to TS was a total game-changer and sped up development massively. Especially when working in a multi-repo situation where there is code shared across frontend and backend, being able to define interfaces ensures the backend and frontend stay in sync. There is definitely a learning curve and troubleshooting compiler errors can be painful but I'd pick that over plain Javascript any day.
JS + TS = C++ ?
It is a common misunderstanding that static type are the only thing that distinguishes languages like C++ from Javascript. A compiler does far more checks than the Just-in-time compiler a JS-engines provides. It can find dead code, does tree shaking, finds errors in code that is not often visited, finds unused variables etc..
Using static types in JS gives you some kind of checks. But in some way it also limits you. Often JS allows to write elegant code that would be much more verbose in other languages.
I´m not sure which one is better. I have beed using compiled languages for a long time, but the reason my JS code crashes is - in most cases - not caused by the missing type annotation. Dynamic types surely enforce a different style and some additional type checks. But TS is not a silver bullet to write error free code.
No offence to anyone, but at least for the frontend/browser environment:
ts = bs
imho.
90% of it is bs.
Simple types: that's good, but that's 10% of ts.
ts was just a utility, now it's a language? i don't think so.
You find yourself needing more than just the simple types from ts? I would take a step back and evaluate. You're making it way way too complicated. Adding layers and abstractions which are totally unnecessary. Think small. (Think component.) Especially in a React app you should lean on React and principles of component based programming to keep your apps simple and safe and maintainable.
Frontend/browser: is a very different environment than the backend/server.
There are very good reasons why js is different than cs.
-- Wouldn't it be nice if we pumped cs into js, and call it ts?
And keep pumping until it starts looking like Perl.
Great. Love it all you can ;o)
To me it's just a tool, 10% of it "is" useful.
Add simple types to js, and ts would be redundant.
Me thinks.