Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Pros and Cons of Using TypeScript

Posted on: 2017-08-09

It's been 3 years that I've been using TypeScript daily. From what I recall, it wasn't yet in version 1, abstract classes were not supported and tsconfig.json file was not there as well. A lot has changed in these 3 years and every two months new features make the language better and better. I recently took some personal time to write two video courses on the subject to demonstrate how great is TypeScript.

However, from someone new to TypeScript and used to JavaScript, it might not sound that great. This is why I compiled a list of pros and cons of TypeScript to help you decide if you should or not use TypeScript.

If you need to debate about TypeScript or JavaScript, you should tackle the problem by first attacking the idea of typed language versus dynamic. This is the biggest battle. Typed language helps on a bigger scale or in a situation where people jump from one project to another. It also helps if you have new people coming in a project to understand faster what needs to be what. It also brings a potential error to the developer by having the code editor raising an error while developing which means less error at run-time. There are countless arguments in favor of strongly typed code. While losing the possibility to dynamically add properties on the fly, you win on having a well-established contract that can be extended if required. Dynamic type brings more drawback in the long term where people can add a property that could change the whole workflow without knowing it while writing type. Strongly typed code auto-document your code by mentioning what is expecting. It also reduces your number of unit tests by not having to check type for each parameter for example.

Here is a list of pros and cons.

Pros

This is a list of pros with some descriptions about why it's a pro.

Combine Three Tools

If you are using plain JavaScript, you are mostly also using Babel. The main goal of babel is to transpile an advanced version of ECMAScript into a version that is well supported by browsers. TypeScript is also doing it while transpiling TypeScript into JavaScript. You need to specify which version of ECMAScript you want the outputted JavaScript to be and it will be done.

If you are using Flow to have typing capability, then you do not need it anymore with TypeScript. It has a strong preference for types. The newest version allows to slack on the strongly typed feature and bring inference as well. Hence, TypeScript can be configured the way your team wants and get the benefit of using the right type of data at the right place.

If you are using React and PropTypes than Flow or TypeScript do the job of enforcing the property types, hence no need to have this other library.

Here is a trend graph of the last year of TypeScript vs Babel under the category programming:

Used by Big Companies

This might not be the strongest argument, but it shows that companies trust the product enough to invest millions of dollars into building with TypeScript.

  • Microsoft
  • Google
  • Slack
  • Asana
  • Ebay
  • Ubisoft
  • Ericsson
  • UpWork (a.k.a Elance)
  • Bloomberg

There is also a list of product that you may know that are made or partially made with TypeScript:

  • Angular
  • Slack
  • VsCode
  • Teams
  • VSTS
  • Office Web
  • Ionic
  • Blueprint
  • RxJs
  • ReDoc
  • Google TensorBoard
  • Tensorflow Playground
  • NativeScript

And here are few frameworks/tools that praise about how great it TypeScript.

  • Aurelia framework
  • Ember Babylon.js
  • Laravel
  • MobX
  • ReSharper

Again, this is more a pro than a con, while not being the ultimate argument. It's just reinforcing that big project benefit of strongly typed system.

Future Features Now

Polyfill is the capability to bring future features in the syntax that developers can use today even if not implemented by the browser or yet implemented by ECMAScript. It creates a workaround with the existing code. This is not unique to TypeScript and BabelJs is a very popular alternative. TypeScript shines by the fact that it does more than BabelJs. However, you will see that is also a cons since TypeScript have polyfill for stage 3 features of ECMAScript specification while BabelJs implement them earlier.

Work with Older Browser

TypeScript allows you to target a specific version of ECMAScript. It means you can target a version that will produce compatible JavaScript for Internet Explorer 11 if you need. If you don't need, you can produce ECMAScript for the latest version of Chrome and be more efficient in performance.

Static Typing

This is the most important and strong argument to go with TypeScript -- it allows to have types. Types can be optional and can be inferred if not explicitly defined.

TypeScript verifies your code on the fly while typing if you are using an IDE that supports TypeScript. This brings a very quick feedback loop to fix errors. Instead of waiting to go in the browser and hit the specific line of code that might be problematic, TypeScript while typing the code let you know that there is an issue.

Static types self-documents the code. Have you ever see a variable "options" as a parameter? What option is available is often obfuscated deep in the code and could be also just used once somewhere no obvious. With typing, the variable "options" will be of a specific type or defined with an interface, hence having a set of possible properties.

Static types reduce the number of errors. If you are using a function that expects a variable, and you send a callback function with 2 parameters in JavaScript, it will just run and maybe or not crash if you passed the wrong callback parameter or even if you thought it was a callback while it was just a value. With TypeScript, while typing the name of the function you would have seen the possible arguments as well as what parameters the callback needs. It won't have let you try something else without warning you.

Having a contract defined remove some hacks in the code. The code is enforced to be in a predicted state which is the one defined by the definition type.

Finally, having type helps new people coming into a project. They do not need to know the whole system to understand a piece of it. Types help them dig into the specific class or interface they need to be aware of, while they can ignore the rest. It also helps people switching from a project. If you are working for 3 months on something, move to something else for few weeks and come back, it's way easier to remember that in that project this class is having these properties and this interfaces than having nothing at all.

Type Inference

This is a relatively new feature that was a big plus of Flow compared to TypeScript. In Flow, the philosophy is that you do not have to define all your types. In TypeScript, you had to do it otherwise it was "any" which is anything. However, since TypeScript 2.1, TypeScript will infer the right type. It means that if you assign a variable a number that this variable will be a number.

let x = 1; // x is a number, not var

This is an advantage for people who do not like the heaviness of typing the type every time and still give good support and validation. It means that it's impossible to assign x to a string from that point of time.

let x = 1;
x = "string here"; // Won't compile since x is inferred as a number

It brings more security and less problematic in code that can be trickier. For example, if you take numbers and return the sum of them. Do you expect to return a number of a string (concatenated value of the number). Well, if your method returns a number (explicitly) it won't compile if one of the parameters passed is a string and that we implicitly wanted a number. Indeed, we could have defined numbers everywhere and remove all the confusion, to begin with.

Inference work as well with a literal object. If you defined an object and assign a value of an integer, the type will be inferred as a number. It means that if you assign to that object's property a string that it will be caught up by Typescript.

let myObject = { a: 1 };
myObject.a = "string"; // TypeScript will catch the inferred type that the property is of type number

TypeScript spreads inference to arrays as well.

IntelliSense

Many editors support TypeScript and provide code completion. IntelliSense increases developers discoverability, bring the JSDoc if defined when typing, inform which parameters can be used as well as overloaded possibility. It reduces potential typos, removes the need to go on the Internet to figure out what properties and functions are available on an object. It increases every developer by enhancing their typing experience which is what a developer does most days.

Avoid Common Errors

JavaScript has common pitfalls that are still very frequent amongst web developer. One of this one is what "this" refers to. With TypeScript, you do not have an issue with "this" since TypeScript figure out for you what it means. If it's "window" than when typing "this." you will see only "window" stuff. If it is referencing the class, you would see the class members. Same thing with variable scopes. With TypeScript, you know exactly if the variable was defined if you are reaching the one you expect hence remove scoping issues.

Real-Time Feedback

All problems with JavaScript are discovered at runtime. The problem with runtime discovery is that you must hit the line of code which may be in a web page very deep under a specific button that is rarely pressed. Still, there is an error hiding there. Going to that page might require several clicks and at the end, you may do a quick modification and not be aware of a change. With TypeScript, while you are typing you are getting feedback. When you are transpiling you are getting feedback and finally, when executing your JavaScript in the browser you can see the error. With TypeScript, you are getting way more feedback from real-time to compilation time to execution time!

Low Entry Barriers

Coming from JavaScript to TypeScript is a matter of hours. I did the jump after many years of being a JavaScript developer and within a full week of work I was already embracing the change. It will be annoying for few hours to have to type more to specify the type, but after few functions, classes, sharing code with teammates you will soon realize that it is worth the few more keystroke required.

It's a low barrier because it's not a new language. TypeScript is a superset of JavaScript. It means that it uses the official EcmaScript syntax, functionalities, primitive types, documentation style, and same libraries. You are used to use "MomentJs" you can. You know by heart all array functions, well it's the same in TypeScript. You do not like the class, but rather to function only, you can!

IDE Integration

There is more and more integration. One of the most popular choices is Microsoft Visual Studio Code, but the list is way bigger than this tool. Take a look and there is probably your tool of choice. If not, you can still use anything else, it's just that TypeScript won't be active while typing, only while transpiling. That said, it's possible to create your own plugin for the editor you use.

  • VsCode
  • Sublime
  • Atom
  • Eclipse
  • VIM
  • Netbeans
  • Visual Studio 2013+
  • WebStorm
  • Emac
  • IntelliJ

Third Most Loved Language in 2017

This one is as well not a very strong argument but put in perspective how TypeScript is perceived. The result is from Stack Overflow 2017 survey. Position 1 was Rust and position 2 was Smalltalk. JavaScript was 11. This is a survey and like all of them not perfect. But it shows that it is not hated, hence give some idea that if you go that way that it might be easier to recruit people to work on your application.

TypeScript vs Dart vs CoffeeScript

Again, this is just to give a perspective against some other alternative. Dart and CoffeeScript tried to help developers by compensating the lack of JavaScript. However, these two requires learning a new language while TypeScript is a superset of JavaScript (extend JavaScript).

On the last 5 years graph, you can see the blue line is TypeScript, the red one is CoffeeScript and the yellow one is Dart.

Compatible with all JavaScript libraries

TypeScript doesn't have a Microsoft repository of libraries for JavaScript like Nuget. While you can find some JavaScript library in that system, the main source is NPM. TypeScript has two way to support JavaScript libraries. The best option which is often (if not always) available is to use definition file (d.ts) which bring only the signature of the public interface of a library. It is integrated into NPM and let you have all the consumption benefit of TypeScript code from JavaScript. In the situation that you are using a JavaScript that doesn't have a definition file, which occurs for less popular libraries, you can still use them but won't get the typing information. Hence, you will be at the same level that if you were not using TypeScript.

Hybrid Mode with JavaScript and Portability

This is mostly new for TypeScript. It can now analyze JavaScript file since 1.8 by looking up .js file instead of just .ts file. In version 2.3, TypeScript can run on JavaScript file and get IntelliSense and some basic inferred type support. This allows converting a JavaScript project easily since you can bring TypeScript without having to rename all the files and without having to bring any TypeScript types, interfaces or other concepts. Once you migrate everything to TypeScript, you can swap the extension file and convert all "any" to a strong type. I'll write a more thorough guide about migrating in a near future.

Remove some JSDoc

I like writing JSDoc, but some people don't. TypeScript allows you to not put as much comment since your parameters are already more documented by the type. For example, if you have a create(user) you may want to explain what is a user in JavaScript. In contrast, in TypeScript you would have create(user:Person):boolean, which is self-explanatory that we need a user of type Person and if successfully created that "true" is expected.

But, in the case you like to comment, you still can and it doesn't need a custom TypeScript comment way to do it. It just uses the popular JSDoc convention. Nothing new and TypeScript leverage your code comment by bringing it with IntelliSense.

Open Source

It's written by Microsoft, but the main repository is open source. You have the best of both worlds. A project backed by people working full time that takes contribution over the world. In the worse scenario that Microsoft pull the plug, the community (which is active) can take over. At the moment, there is release every month and more than 25 people outside Microsoft contribute in average on each release.

Living Project

Not only it is open source, it is very active. A new version every month. More than 18 000 commits, with 47 official released version.

Refactoring Tools

This depend on the IDE you are using, but since TypeScript brings types, it's easier to find refactoring tool. Renaming a class or function is a breath since it will affect only the right one.

Reduce the Amount of Unit Tests

Without TypeScript, more unit tests are required to be sure that we check for a specific type. For example, you are writing a function that takes an array. In TypeScript, you do not need to check if it's an array of integer because TypeScript enforces it for you. However, in JavaScript, you will need to do a check to see if it's an array, and then to check if the array contains all numbers. These checks will need to be unit tested.

Future Proof

If TypeScript die, you can always use the generated JavaScript. At this time, generating in EcmaScript 6 produce a very understandable JavaScript. Also, TypeScript has been built in a Microsoft's fashion in term of compatibility. They have in mind to always (finger crossed) be backward compatible which is true since version 1.0.

Nothing Proprietary

Microsoft didn't reinvent the wheel. As mentioned earlier, it uses NPM and follows EcmaScript. It doesn't use any proprietary tool, technology or language. This is not Silverlight, Nuget or XAML.

Leaded by Experimented Engineer

TypeScript is lead by Anders Hejlsberg. He is the creator of Turbo Pascal, Delphi, C# and now TypeScript. Lots of experience behind creating language. This might not be a very appealing argument, but it's still more appealing to know it is lead by someone who has experience about what is good and wrong in language.

Linter Compatible

TypeScript as a TsLint plugin for many IDE and can run normal linter with the normal JavaScript rules. No need to learn something new. It's using what everybody know.

Debugging Capability and Options

You can debug your Typescript directly. Or, you can debug the generated JavaScript. You can do it directly in your browser, or you can do it in your IDE. As you can see, TypeScript doesn't limit you and you can embrace the way you prefer to debug the code.

Easier with Merge Conflict

You are merging and getting conflict, you fix them all and that's it. What happens if you had bad merge? Hard to know until execution. With TypeScript, you open the IDE and see right away what went wrong. A missing variable, a duplicated line, a missing brace, a function that returns something wrong, etc. You can fix them all before compiling, Lintin or executing the code in the browser. Again, smaller loop to feedback which makes big merges way easier to fix with confidence that nothing is breaking.

React Compatible

The extension won't be JSX, but TSX. Other than that, TypeScript will build like Babe would do JavaScript. Definition files for React are up-to-date and Microsoft is using TypeScript and React internally so they have the interest to have the definition files always at the latest version.

Create-React Option for TypeScript

There are two versions at this moment. One maintained by Microsoft and one by an independant person. This is great since it is often used to bootstrap project. You are not left alone with TypeScript and have all the advantage the main project is having since the TypeScript version use the main create-react underneath.

Merge Conflicts

Merge conflict are simplified. Once you are done merging, you can see right away if something won't compile in TypeScript. You have the IDE highlighting all potential errors and the TypeScript transpiler not letting you generate the JavaScript. Surprisingly, this happens quite often while merging and missing a curly brace.

Cons

TypeScript is not perfect and has also some cons. In my perspective, the pros overweight the cons and feel free to comment if I am missing any cons that I do not see.

Compilation Time

This is a con since you must transpile your TypeScript into JavaScript. It takes some time. However, most JavaScript project use Babel to transpile from one version of EcmaScript to another. It means that that the cons is only one if you are using vanilla JavaScript without any transformation. There is some way to improve the transpilation time by just compiling specific folders or by just compiling specific files. Also, it's possible to divide a huge application into several pieces where one piece can rely on the definition file generated by the other area. This latest suggestion allows compiling a big chunk of code that doesn't change often and have the other piece of code to use the generated JavaScript with the definition file. Only the piece that the developers are working on can be compiled. It's a little bit messier to setup, but still a viable approach.

Babel as more Feature than TypeScript

TypeScript will be behind Babel as far as feature completeness goes because features need to be built by Microsoft. This is almost not a cons because Babel must also implement the polyfill too.

How cutting edge we need to be is also questionable here. Babel is having 40% of ES2016, TypeScript 36%, not a huge difference since it’s only 2 features. TypeScript rule is to only have polyfill for stage 3 and above, Babel brings earlier stage. The justification of Microsoft is that they want to always be compatible from version to version and some early stage feature could be dropped or changed.

Less flexible and Less Dynamic

Less flexible than JavaScript. Type for example constraint what can be passed by argument. This is seen as a con by many hardcore JavaScript developers, however, we saw with PHP that being too flexible leads to some disaster. While some dynamic type can have in specific scenario some great strength, in most cases it causes chaos and maintainability. Still worth mentioning that TypeScript can be less flexible if "no any" is enforced.

Definition Files Required and not Up-to-date

Some libraries may not have up-to-date definition files or not a definition at all. This can be annoying, but it doesn't block you to use those libraries. It will just not have great IntelliSense or you may have to use "any" which would be the case without TypeScript.

Less Examples of Code

For me, this is the biggest drawback of TypeScript. There are obviously fewer examples written in TypeScript than in JavaScript. It's not that hard to create a mental mapping between the two since they look alike, but sometimes a simple copy-and-paste is just not possible. It can be annoying. With experience, you can copy-and-paste the JavaScript and convert it to TypeScript rapidly, but still annoying.

Less Support

If you have an issue in JavaScript you will get way more people jumping in to help you. TypeScript is a subset of JavaScript in term of developer that use it. It means that most TypeScript developers would be able to answer questions about JavaScript, but the other way around might not be true. It's becoming more and more popular, so it's not impossible to get support, but JavaScript beats TypeScript.

I realize that the list is getting quite big. I encourage anyone to start a small project in TypeScript and see the benefits by themselves.