Why so much hype over Typescript ?
Tags: typescript, javascript, webdev
Published: 2019-09-24 14:28:51

## Some context

First of all, don't misunderstand me, **TYPES ARE GREAT**. I use Typescript everyday at work and the goal of this post isn't to question the benefits of a type system. Because types give context, save us from stupid mistake and allow us to avoid performance issues by avoiding most of the automatic type inference performed by js interpreter during JIT compilation and run-time. I think that anybody should use a typing system while building javascript if he ever think to share it or to maintain it in the long run. 

But as much as I appreciate the benefits of Typescript as a type system (even if several of my coworkers use so much **any** that in most places of the app it doesn't bring any benefit at all compare to pure javascript). I'm skeptical about Typescript as a compiler. All the following argument and reflexion concern Typescript as a compiler and a superset of javascript instead of a type system enhancing javascript. 

## It add a lot of complexity for minimal benefit
While using typescript you need to configure it and it's not simple. The options are not clear at all and documentation is obscure. As an example, ask yourself what are the differences between *target* and *module* options.
Ok, so target is straightforward *spoil: not really* it's your target environment...
But wait ?!? What exactly is ES2017 ? And ES2018 ?
Let's take a look at ES2017 as an example:
  - [Object.values](https://caniuse.com/#search=Object.values)/[Object.entries](https://caniuse.com/#search=Object.entries);
  - [String padding](https://caniuse.com/#search=String.prototype.padStart); 
  - [Object.getOwnPropertyDescriptors](https://caniuse.com/#search=getOwnPropertyDescriptors); 
  - Trailing commas in function parameter lists and calls; 
  - And [Async functions](https://caniuse.com/#search=Async%20functions). 

Ok, Great. But which navigator are supporting this exact set of features ? Other question, did you knew that ES2017 was this set of feature without checking the can i use link ? I didn't.

So using the target options you have to know which version of ECMAscript the feature you want is from. Then you have to check if your target browser support this feature or (if the feature is polyfillable) write the code anyway and deal with the bloated code. If you check the can i use link you should also have noticed that even if all this list of features are part of ES2017. It doesn't mean anything for the browser version. Because web browser implement ecmascript features independently. If you were using Babel you could use @babel/preset-env and using [browserslist](https://github.com/browserslist/browserslist) target exactly the browser you want with **meaningfull** query (Nota: you should still be carreful [about production bloat](https://medium.com/@WebReflection/avoiding-babels-production-bloat-d53eea2e1cbf) but you can be more serine knowing that at least the code you're shipping to the user is useful)

There is also the fact that the compiler options include options about minification. Which could be explain by the fact that typescript goal is to handle completely the bundling process. But it's not the case. In most case you still need to add a real module bundler to you build chain to be able to make something real with typescript.

Finally there is the fact that the typecript compiler have some constraint. For example if you want to use dynamic import you must use *module: "esnext"* which you can't if targeting ES2015 even if you bundler (webpack or parcel) support it. Which means you can't split your code while targeting legacy browser...

## Typescript isn't really a superset of javascript anymore 
There are some differences between pure javascript and typescript. For example between @decorators in typescript and what is currently being normalized in ECMAScript. Which will probably lead to some difference at run-time when using them once they are implemented natively by browser. 

In addition of that it is possible to write **today** [valid code which would be parsed differently by the typescript and the javascript](https://medium.com/@jasvir/monoglots-when-a-subset-is-not-1604e3a51d9) parser which will lead to different run-time execution. I know, I know, it's really unlikely that you ever encounter any usecase like this one. But it doesn't stop the reality of this.

## Use JSDoc instead
As I said before, I still think we should type our code. In fact it's really easy to do it even without typescript. [We just have to write JSDoc declaration in plain javascript file](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html). 

We can then use typescript to type check them with the --CheckJs option.
You can also set VS Code (and probably most of the text editor and IDE in the wild) to show type checking on JS file by enabling Check JS in the parameters. 

A big advantage to use JSDoc instead of typescript is that you write javascript which remove any need for a compilation step. You can still use babel if you want but you can also be happy with Javascript.

Some ressource about JSDoc:
- [Type Safe JavaScript with JSDoc](https://medium.com/@trukrs/type-safe-javascript-with-jsdoc-7a2a63209b76)
- [JSDoc.app](https://jsdoc.app/)

--- 

Now, I'm not asking you to ditch typescript. If you're happy with it, stick with it. I'm just wondering why everyone jumped in the typescript train when for the most part I see more constraint than benefit compared to a some regular types included in comments. 

--- 

PS: I didn't talk about tslint vs eslint [because everyone agree on the superiority of typescript](https://eslint.org/blog/2019/01/future-typescript-eslint). Since I talked about browserify, I must also talk about one of my favorite plugin for eslint which is [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat)

PPS: English is not my native language so don't hesitate to correct anything. I used a corrector but its probably not perfect.