Published
- 9 min read
Typescript - Myths vs Reality
Photo by Eva Elijas from Pexels
There is always some resistance when you introduce TypeScript to a codebase. You probably will run into a couple of misconceptions and myths surrounding TypeScript. Let’s debunk the following myths:
- TypeScript Slows Down Development
- JSDoc Typings are enough
- TypeScript prevents all bugs
- TypeScript adds clutter to the codebase and more bugs
- TypeScript Compiler Errors are no real bugs
1. TypeScript slows down development
TypeScript requires some additional setup, needs to be compiled, and you have to write more code. Thus TypeScript development must be slower.
Lets take a look at the entire development process:
- Initial Setup
- Compiling
- Writing Code
- Reading Code
- Changing Code
Setup
JavaScript projects usually will set up the BabelJS compiler and a packager like Webpack.
TypeScript projects are set up identically. The only difference is that you have to add an additional BabelJS Plugin to remove the TypeScript typings. In addition you use the TypeScript compiler to check types.
The effort for both is identical.
Compiling
A typical Frontend Development project will have two separate processes for development and for production. The compilation time of both processes can be quite different.
Compiling during development you will be using BabelJS for JavaScript or TypeScript, the processing time is identical. For TypeScript additional type checking will be done by your code editor in the background.
Compiling for production will add for TypeScript an additional compile step for type checking. It can be run in a separate process. It can add a small overhead. However since a production build is run by a CI/CD Pipeline it should not impact your development velocity.
The effort for TypeScript is minimally higher.
Writing Code
When writing new code developers have to start to consider types - this makes writing TypeScript ‘slower’ than writing JavaScript. This is a very good thing. It is the first minimal step to actually think about code design before you code.
For developers that are used to dynamic typing it is initially hard to take types into consideration. But with experience and familiarity you will barely notice a difference.
Reading Code
However, writing is only a small part of development. Reading code is a much larger part of development. TypeScript significantly improves readability.
Look at this example:
const initJS = (options) => {
...
}
const initTS = (options: { debugMode: boolean}) => {
...
}
With initJS
you are going to have to read the entire implementation to figure out what parameters you can pass to options
. Yes, I know you could use JSDoc to describe it, however as you can see with this example the developer that wrote the code did not add that comment.
With the initTS
it is clear that you can set the parameter debugMode
. In Addition, not only is it easier for humans to read the code, your IDE can now also provide you with significantly more accurate autocomplete. Saving you even the switch to the file when you want to call the function.
Adding types will not only improve your function signatures, it will also make it much easier to understand the implementation. In addition it prevents code smells like reusing the same variable for multiple different contexts.
Changing Code
With JavaScript if you change a function signature, you have to manually check every piece of code that is calling the function. If you miss a single adaption, you will first see it when you run that piece of code. If that piece of code is not run very often, or a different developer encounters it you will waste a lot of time on debugging to figure out what exactly happened.
With TypeScript this is done by the TypeScript compiler and it provides you an output of all the instances where the code will now run into a problem. While you are developing you will be able to fix the issues immediately.
Summary
Does TypeScript really slow down development?
- Initial Setup - Identical
- Compile Time - Identical
- Writing Code - JavaScript minimally faster
- Reading Code - TypeScript faster
- Changing Code - TypeScript significantly faster
Yes, TypeScript adds a small overhead to your project, but at the same time it drastically increases your development velocity.
2. You do not need TypeScript - JSDoc static typing is enough
JSDoc allows you to define types with the @type syntax. This allows you to document your code like this:
/**
* Simple Addition
*
* @param {number} a
* @param {number} b
* @returns number
*/
export const add = (a, b) => a + b
add('12', 2) // Argument of type 'string' is not assignable to parameter of type 'number'.
This annotation is a significant improvement compared to undocumented code. In addition code editors will now take this comment and interpret it and display warnings in your JavaScript code.
The argument is now: Well we already have basic type support why do we need the typescript compiler?
- You only get warnings for files you are currently looking at, you are not aware of files that stopped working because you changed the function signature. The TypeScript compiler will throw an error for all files impacted by the change.
- They are comments, developers tend to forget to update them correctly.
- You are limited how to defining complex objects or how to reuse them.
- You do not benefit from the existing TypeScript definitions provided by the TypeScript community.
- By using JSDoc you are utilising already the TypeScript compiler. Your code editor just runs it in the background to generate the warnings. You can learn more about the feature here.
Using JSDoc is a great starting point to get your team familiar with defining types.
It does not make sense to only use a small subset of TypeScript with an overly complex syntax that some developers forget to update.
3. TypeScript prevents all bugs
No it does not. It prevents the most common type of bug in JavaScript a TypeError.
You should use testing strategy like Test Driven Development to eliminate even more bugs. Ideally you are using a combination of TypeScript and tests. By using TypeScript it makes it easier to write the tests, and you are not constantly writing tests to ensure the correct type.
AirBnB estimated that 38% of bugs can be prevented by using TypeScript. Even without any other benefits - just to reduce 38% of bugs is already a very big deal.
4. More clutter more bugs
More Lines of code more potential bugs. Yes, this partially true. With TypeScript you introduce the possibility of incorrectly defining your TypeScript types. Again, TypeScript is not a test strategy. You have to add testing.
However if we add the same functionality of TypeScript to JavaScript, you will see that TypeScript actually reduces clutter:
const addJS = (a, b) => {
if (typeof a !== 'number') {
throw new TypeError('a is not a number', a)
}
if (typeof b !== 'number') {
throw new TypeError('b is not a number', b)
}
return a + b
}
Compare this to a similar code in TypeScript:
const addTS = (a: number, b: number) => {
return a + b
}
While it may appear to be more clutter in TypeScript, most likely you are not writing any type checks in your current JavaScript code, and have many potential sources for Type Errors.
5. TypeScript Compiler Errors are no real bugs
You have a legacy codebase - the team is convinced - the code is ‘bug free’. Now you add TypeScript to this codebase and suddenly TypeScript outputs hundreds of compiler errors.
The first reaction is going to be denial, these ‘errors’ are not real bugs. There is no need to fix them.
This is true for the moment. The code is seemingly working correctly if nothing changes, the inputs are always the same, the output is going to stay the same. In practice however you are adding new features and are fixing bugs in the ‘bug free’ software. Things are changing all the time in the codebase.
You should be treating the TypeScript compile errors as bugs, so that you can fix them as fast as possible. Only a small percentage of ts errors are false positives, usually because of some sort of compiler setting.
Having TypeScript compile errors is an indicator of an unstable system. When you start to analyse and fix the compiler errors you will find:
- Actual bugs - In a large codebase, you can be sure that there are several bugs caused by TypeErrors
- Outdated Libraries
- Problematic patterns that were used in the codebase
All of these things have to be fixed eventually. The code quality will be greatly increased when you address these issues. If you do not fix these issues in a timely matter newly introduced errors may be lost in the existing errors and you will continue to waste a lot of time debugging.
When all compile errors are resolved you will experience all the benefits of TypeScript.
The first major benefit is that you cut down your debugging time. By reconfiguring your pipeline to fail as soon as it detects a new TypeScript error, you can prevent most TypeErrors of ever reaching production. This early detection of errors will tell you exactly which line is causing the issue and you then can fix it in a matter of minutes, instead of debugging code for several hours.
With the power of compile errors, you can fix these errors before running your code which in turn greatly Increases your development velocity.
Bonus: Python is maintainable and does not need types
A large Python project is also subject to similar problems like a large JS codebase. To make Python more maintainable Python 3.5 introduced types in a very similar fashion as TypeScript.
https://docs.python.org/3/library/typing.html
Summary
Most of these myths were created by a lack of experience of using TypeScript. It is understandable where the core idea of these myths come from.
Starting to use TypeScript is hard. The reason for that is because you’re starting to think about code differently. You’re starting to take into consideration what datatypes are used. This shift of thinking makes the entire development less error prone.
The reality is, using TypeScript will improve you codebase in many different aspects. The collective benefits far outweigh the negatives.
But, nobody really can be convinced a myth is wrong until they experience for themselves. So go and start using and experiencing TypeScript on your own.