TypeScript has become a game-changer in modern web development. When I first started coding, JavaScript was my go-to language for everything, from frontend to backend. But as my projects grew in complexity, I started running into challenges: runtime errors, unclear codebases, and a lack of confidence in my application’s stability. That’s when I decided to give TypeScript a shot—and I haven’t looked back since.
This article delves into my journey with TypeScript, highlighting its impact on my development process and the compelling reasons why I believe it’s an essential skill for every developer.
The Problems with Vanilla JavaScript
When working with JavaScript, I loved how easy it was to get started. The language is flexible and forgiving, but this can be a double-edged sword:
-
Runtime Errors: I can’t count the number of times I encountered bugs because of unexpected
undefined
values or type coercion. - Lack of Clarity: In larger codebases, keeping track of variable types and ensuring consistent function arguments became a nightmare.
- Debugging Hassles: Many bugs could only be caught at runtime, making the debugging process tedious and time-consuming.
These challenges made me realize that I needed a tool to enforce better structure in my projects. That’s where TypeScript came in.
What TypeScript Brought to the Table
TypeScript is a superset of JavaScript, which means it builds on JavaScript by adding static typing and other powerful features. Here’s how it solved my problems:
Static Typing for Peace of Mind
With TypeScript, I could define types for variables, function arguments, and return values. This ensured that I caught type-related errors during development rather than at runtime. For example:
// Static typing: a is a number, b is a number, and the returned value of the function will be a number too.
function add(a: number, b: number): number {
return a + b;
}
// Error: Argument of type 'string' is not assignable to parameter of type 'number'.
add(5, "10");
Improved Developer Experience
TypeScript’s integration with modern editors like VS Code provided me with features like autocompletion, intelligent suggestions, and inline error reporting. This made writing code faster and less error-prone.
Enhanced Code Maintainability
By enforcing strict typing and enabling features like interfaces and enums, TypeScript made my codebases more readable and maintainable. It was easier to onboard others to my projects since the types acted as a form of self-documentation.
Better Tooling
Tools like ESLint and Prettier work seamlessly with TypeScript, enabling me to enforce coding standards and maintain consistency across projects.
Why Every Developer Should Learn TypeScript
If you’re on the fence about learning TypeScript, here’s why I think you should give it a try:
- It’s Industry-Standard: TypeScript is widely adopted by companies and frameworks like Angular, Next.js, and React.
- It Reduces Bugs: Catching type-related errors during development saves countless hours of debugging later.
- It’s Easy to Learn: If you know JavaScript, learning TypeScript is straightforward since it builds on what you already know.
- It Scales with Your Projects: Whether you’re working on a small side project or a massive application, TypeScript grows with you, ensuring long-term maintainability.
Conclusion
Switching to TypeScript has been one of the best decisions I’ve made as a developer. It’s improved my productivity, reduced my stress, and made my codebases far more reliable. While the initial learning curve may seem daunting, the long-term benefits make it well worth the effort.
So, if you’re looking to level up your development skills, I highly recommend giving TypeScript a try. It might just become your new favorite tool—as it has for me.
Top comments (27)
Don't make the mistake I did, however, and try to refactor a WIP project from JS to TS. It's a nightmare.
I'm going to have to learn TS on something from scratch.
You are true! TS until don't get enough experience of it is harder at first sight - this is same for JSDoc also which is technically TS just a bit better.
my answer for title:
Because they are don't know the JSDoc are better:
-- this generic also works in TS, my opinion of TS vs. JSDoc is: dev.to/pengeszikra/jsdoc-evangelis...
... my real world, a bit complex than a TODO list example:
dev.to/pengeszikra/javascript-grea...
I wouldn't necessarily compare between TS or JSDoc because each of them has its merits and values. JSDoc is strong for explaining JS code with the use of written types, but not as flexible when it comes to custom types that can be abbreviated, like TypeScript.
Where JSDoc misses, TypeScript shines. Conversely, TypeScript is sometimes not as safe as it seems and could largely vary with the compiled JS code based on the compiler, which lacks consistency sometimes, something which is not a problem on JSDoc.
Technically behind of JSDoc is working a TS but a different way. I can handle a same complex type as in TS. That why my first example is using a generic. But there is a npm module for React useReducer with typesafe handling maded by JSDoc
But show me a TS type which I cannot reproduce in JSDoc.
Technically, JSDoc and TS are of the same quality in terms of the types you can explain. However, there are specific assisting measures in TS that help describing types more easily. I talk about types like
Pick
,Omit
andPartial
, which are extremely useful for explaining other kinds of types. Unlike TS, in JSDoc you'd have to explain the types with templates which are not as comfortable to use.Let's take an example of the type User. I'll define some relevant types that can derive for this too.
When it comes to more and more properties on a single type, it is safe to assume that it'll be more and more difficult expressing different types and interfaces which derive out of the type that you want to base your annotation on.
Pick, Omit and Partial ar working in JSDoc also
Templates in TS or JSDoc are capable to handle client side defined types, which means if I write a library which is depend on user type then itt can be pass throught the templates. So knowing how works the templates is crucial in TS / JSDoc to work efficient.
The biggest advantage you mention is already being fixed in nodejs and most other runtimes had typescript support out of the box. Only the browser remains as a place where you can't run typescript directly, but nobody I know runs uncompiled code in the browser, whether they use vanilla js or not. 🤷
This is just a half solution and bleeding in many angel. Because if nodejs are make a runtime typecheck on TS code in JS before the JS JIT are run the code that means it is slower than run a pure JS code.
But I readed the nodejs solution, which is technically just a type stripping. Which is also spend a time, but lot less than a runtime type checking.
I don't know the other runtime solution. But the pervious sentence is right for them.
Other problem with this node fix thing is: on company projects are run on dedicated node version, because that is don't realistic to uppgrade every package capable to run on a latest node.js. That is a pain point of legacy codebase. Year by year that is worst.
The frontend code is run on browser, so don't option to not compile TS.
I use uncompiled code in browser, and thx that way is working very fine, also that is important, because not every js code are compiled a classic way, some are uncompiled when for example just copy paste in a wordpage or any other PHP backend. But when other non JS BE are generated html page with js code is also question that code is compiled or not.
That why JSDoc have advantage of TS.
I use uncompiled code in the browser too. I mean, there are loads of cases where adding a build step is just bloat, so why wouldn't I?
You don't use something like babel at all to transpile your JavaScript? I don't even want to imagine sending more than a few lines of JavaScript to the end user without at least transpiling it first...
In a ideal world I don't transpile my code. I belive we are going to a direction of ideal world. Technically I wrote a POC level games and markdown view ( with a ) without any compile, even I write JS directly into HTML page, so technicallly that project are started a few plain single HTML page. Bit later if I reach a more than few lines I push js to js file. But even that moment is don't need to transpile my code. In that way I can keep my focus on the floor, and exactly know what is need to be do on core HTML level, to everything is working as I plane.
To proof is everything is works, just open my markdown editor and write on
and that is run my html games on my markdown without any compile. This stuff can easy check on any (modern) browser or device.
But at the end - why this world is fare from ideal - I need to use a minimal build for hot-reload development, which is also don't transpile all of my code.
Vite uses a built-in transpiler and can handle typescript code without any problem...
Yes I know, but I am just use vite as development help.
My point of view is the JSDoc are fare versatile solution compare to TS.
Because if paste my JSDoc code to any where, where JS can run that is run without any extra step, instead of TS code.
Plus TS code syntax is make a noise to a JS code.
Make a import name conflict also.
That is one of the biggest mistakes people make.
compiles to
If you have
add(5, "10");
in the codebase it will register an error. But after it is compiled the function executes without an error.On a server it is not a problem, but the code you push to the browser is public.
You're absolutely right to point out the difference between TypeScript and JavaScript, and I appreciate you bringing it up. TypeScript's static type checking happens at compile-time, which means that while we might catch type mismatches (like add(5, "10")) during development, the compiled JavaScript won't enforce those checks during runtime.
As you mentioned, this is not as critical on the server-side, where type errors can be caught in a controlled environment. However, when it comes to the browser, it is important to be mindful of how the JavaScript is executed in a public environment. This is where additional runtime validation (such as input validation or using runtime type-checking libraries) can help ensure the safety of function inputs, which was outside the scope of my article, but definitely a key point to consider in real-world applications.
Thanks again for pointing this out!
I use javascript with value objects.
And that solves the problem on the server and in the browser, without any dependencies.
Typescript for me a solution that gives people a false sense of security. When people that use compiled languages see typescript, they can think it behaves as their language. And for people that start programming, they won't understand the difference between checking at compile time and checking at runtime.
Your provided code is clearly checking for a number type on the NumberValue class - No doubts about that. However, the solution is rather lengthy and won't be reusable for different kinds of values. For your example, it definitely serves as a good solution.
For cases in which you need a wider range of applicable solutions such as yours, I would suggest using
Zod
orYup
which are excellent libraries used primarily for form validation.I'd argue that there is some merit to this, however it misses the point of stricter type checks and the ability to create more robust code with the use of types. Sure, compilation to JS does stuff to the code and strips off types in the process, but overall it's a superset of JS so it is expected to sometimes have problems when compiling down to JS.
I agree with you on that one. Personally, I wouldn't advise learning TypeScript before JS because you could get into the assumption that everything works the same after compilation, and that is not really the case with such a complex language like JS, that TS code is compiled to.
How is it not reusable?
I agree it is lengthy, but creating a data object in these times of AI is not more than one line of text.
Data objects are also composable, so you can add wrap a basic data object in an object with specific business rules or combine multiple ones in a bigger object.
The problem with the libraries is that they serve one purpose, form validation.
Data objects can do anything you want them to do, because a part of the definition is that the data must be valid.
I agree typing is a good thing.
I was listing a few cases where typescript can be a cause of problems because people are not aware of the trait offs that have been made by the language.
And because it is an industry standard, I think it is a very dangerous language.
My intent here is not to put words in the mouth of the OP.
I believe what OP meant by
Is that your value object constructor hard codes the type check for
number
.So, if you want to use this technique in a larger setting, you would have to create a value object class for every type.
If you're working with n custom types, then you would have to write/generate value objects with getters and/or setters for every JS primitive, and use those wrappers for every field of every custom type right? And custom types are often composed of other custom types.
Depending on how dogmatic you want to be with this approach, do you trust types and functions from 3rd party libraries? Or do you have to decorate them to ensure all of their types and function arguments and return values are safely wrapped in value objects?
I see your point there. It just seems like a lot of boilerplate.
I'm not saying you're wrong. There absolutely could be something I'm missing or some way to handle value objects more gracefully.
Side Note: Just being honest here, I haven't used TS/JS in about 6 years. So I'm a bit rusty to say the least. But there will always be a special place in my heart for TS/JS. I often miss it.
I didn't show the full code of a value object. I wanted to highlight the validation part to show types are not needed when the arguments of a function are checked.
The idea is that there is validated data before starting the logic the application needs.
That logic can use the value object as a function argument, and then just check for the value object name. So without much effort the value objects created a sort of type system in a non typed language.
Or the logic uses the field values, as you see in the example I provided.
There are not that many primitives in javascript, and the only ones that warrant a data object are string, number, bigInt and boolean.
The primitive value objects are what I call utility value objects. The magic starts once specific value objects are created. Then those value objects allow you to use naming for objects that both developers and business people have agreed on. Which makes the communication more transparent.
If you want to learn more, value objects are a part of domain driven design.
You are right, on runtime that function is don't make any type checking. The TS/JSDoc goal is eliminate development time type mismatch as many as possible.
That why a JSDoc a bit more clear because you know a remmark don't affect your running code.
TS is looks like a real part of code, but also don't.
I totally agree! TypeScript has made a huge difference in my workflow as well. The static typing and early error detection really help catch issues before they even get to runtime Edu Updated. It’s definitely a game-changer for any developer looking to improve code quality and confidence.
TS is just a type compiler, linter and language server. It is a pseudo language that aids in JS programming through compile time type checking.
Not necessarily everyone should learn it except if you are working with JS.
Obviously, TS is something you have to learn after you make use of JS because it's a direct superset of the language. Regardless, there is merit to understanding static typing even if it comes to an interpreted language such as JS, which TS is compiled to.
Sure, if you use Python then you have no interest in learning TS unless you work with both Python and JS. At the end of the day, it's up to you - I just really recommend learning TS because it gives you a taste of static typing which is not found in high - level languages.
Learning TypeScript has been a game-changer for me as a developer. Its static typing, scalability, and enhanced tooling have helped me write cleaner and more maintainable code. I applied this knowledge on Blacksmith Leather Apron to improve the overall development process and enhance the user experience.
What about us, desktop developers? :I
Or... Just stay clear of JavaScript and all of it's descendants. Let it die and bring on a better technology.