Our reason to switch
With TypeScript being statically typed, we set a few goals the switch should provide. One of the goals was having a more strict codebase, which should make it easier to review the code authored by other people, easier navigation through the codebase and elimination of bugs which could be prevented ahead of runtime by means of TypeScript’s static analysis. With the goals being set, let’s analyse the results we’ve observed.
In order to ease the setup of the project's repository, we suggest using one of NodeJS TypeScript starter repositories authored by the community. Our starter repository of choice was Microsoft’s TypeScript Node Starter, freely available GitHub.
This specific repository comes with a variety of packages, preset scripts and tooling already set up. It also removes the need to wire everything manually and showcases the project’s folder structure.
It is a widely known fact in computer science that statically typed languages remove a whole class of bugs which would otherwise only be discovered by testing the application. Among them is discovering type mismatches. For example, summing up a number and a string is an undefined operation, which would result in an undefined or weird behaviour of application, but is prevented by a compiler pretty much immediately.
The first one is to write the type package by ourselves. This approach can be tedious and often painful, as in most cases, the library documentation does not state the possible parameter and return types. This means we’ll need to look at the library’s source code and figure out the full type definition by ourselves. If the library has a large number of functions, this process can take days.
The second option is to simply define a module of type Any. Any type is a special type defined by TypeScript, which tells the compiler that a variable's value can be anything. This means that the compiler will not complain about it, but we’re losing aforementioned benefits, including static-analysis and ability for editors to auto-complete our code.
What we learned and our suggestions
If you’ve got this far, you probably already know that defining types in TypeScript is of great importance. So is type-casting, which is a process of converting one type to another. Perhaps this becomes most noticeable when we’re dealing with calls to external APIs. Of course we have an option not to define the types and not be bothered by the compiler, but doing that goes against TypeScript’s best practices.
In this particular case, we’ve opted to use a validation library. A good TypeScript validation library will solve two issues. Firstly, we can set up validators for external APIs, and secondly, it will generate us the necessary types, removing the need to define them manually.
Most importantly, do not turn off compiler errors and warnings. TypeScript does provide a way to do this, either for the project as a whole, or just for specific lines of code. In our experience, one should do that in very rare cases. Before doing it, stop and review what the compiler is telling you. In almost all cases, we figured out suppressing compiler errors and warnings would actually be a bad idea.
Overall, our experience with TypeScript is very positive. Static typing caught numerous bugs in the early development stage, which would otherwise be caught much later in the process or even sneak out into the production environment. Being a little bit more verbose for a good reason, it means there will be cases where some extra code will need to be written, but we believe that in most cases, the pros outweigh the cons.
Want to chat more about how we can help you elevate your tech venture with our web development services?
Get in touch at firstname.lastname@example.org.