I Was Wrong About TypeScript, Here is Why

I Was Wrong About TypeScript, Here is Why

When something new is announced, people have a tendency to choose sides. When TypeScript was announced, I wrongfully picked a few key concepts that didn't resonate with me, then chose my side: against. In this blog post, I'll try to explain what I was thinking when TypeScript was announced and how I realised that there are great minds behind it who really know how to create benefits without big sacrifices.

Initial thoughts when TypeScript was announced

When Anders Hejlsberg is working on something, it automatically gets my full attention. He has close to 30 years of experience in building compilers and designing programming languages. You can read more about his involvement in various programming languages on his Wikipedia page.

When I heard that he was working on a language that is transpiled (aka source-to-source compiled) to JavaScript, my initial feeling was a disappointment. Microsoft is going the Dart/CoffeeScript route and rejecting the ECMAScript standard. I am not going to learn a new language and forget everything I learned just to express something in a shorter form. There must be something more on offer.

I also had bad memories of how Microsoft tried to get Windows developers into Web development by introducing ASP.NET Web Forms. Web Forms abstracted away the core technologies of the Web with mixed results. Is TypeScript aimed towards C# developers that "can't" learn JavaScript; is it a new language that has features that are familiar to C# developers?

Even with Hejlsberg on the team, I simply could not get excited about TypeScript, and I didn't dig deeper. I completely missed a few key points of the language and compiler.

Getting immediate benefits from TypeScript

In a recent client project, TypeScript was used with React and Redux. React and Redux were both familiar to me, and I had been writing modern JavaScript (ECMAScript 2016, aka ES6) for six months.

One way to get started is to pick your favorite editor (for example, Visual Studio Code, Sublime Text, or Atom) and run the TypeScript compiler from there. I installed the TypeScript Sublime Plugin and tested a few autocomplete suggestions on native HTML elements.

alt-text

Technical note: Text editor plugins use one part of the TypeScript compiler's API: Language Service. Language Service is designed for text editing when low-latency feedback for the developer is crucial. They provide beautiful API methods like getCompletionsAtPosition, which is used in the example video above.

TypeScript with 3rd party libraries

We haven't written any TypeScript yet, only ES5 source code in a file that has the .ts extension. We can get even more benefits from the compiler by getting the API description to the 3rd party libraries. The API description is called Type Definition in TypeScript.

Let's download a popular view library, React, and type definitions for it. You can identify type definition files by the "d" in the filename, for example, react.d.ts.

The tool for managing type definitions is called Typings.

To install Typings: npm install typings -g

You might find the Typings command line API familiar; it is very similar to the one used with npm.

After installing Typings, you can use the init command to create a config file: typings init

Search for type definitions by name using the search command with the --name flag.

> typings search --name react
Viewing 1 of 1

NAME  SOURCE HOMEPAGE                         DESCRIPTION VERSIONS UPDATED
react dt     http://facebook.github.io/react/             2        2016-05-26T13:46:01.000Z

The "dt" refers to the source location of the type definition; it can be npm or a popular site called Definitely Typed (dt), for example. A list of sources can be found here.

Type definitions are installed with the install command.

typings install dt~react dt~react-dom --save

The flag --save has behavior that's similar to npm's --save flag: it saves the type definition reference to typings.json, which was created with the typings init command.

We are still missing React itself, which can be installed with npm:

npm install react react-dom --save 

What is development like now that we have the 3rd party library and its Type Definition file? I made an example React component with two properties and observed how autocomplete works when I use or edit the component.

alt-text

In the example, I added my first snippet of TypeScript, the interface declaration. I am not keen on adding types in every situation, but describing the public-facing entry points (such as the component's properties) is beneficial.

Benefits of type definitions

Now that you don't have to remember or peek at the API definition, using the API is easier. Refactoring is also much easier.

Imagine that we have a DemoComponent that is used inside many other components and needs different properties. For example, it has a name property that must be changed to something more specific (username, surname, fullName, applicationName, etc.). If you search and replace with the keyword '.name' in a large project, simply put, you're screwed. You have to check each occurrence for the correct context. When types are used in the correct places, the name property has more semantic meaning and, therefore, the tool knows which names will be affected by refactoring:

alt-text

The example shown in the video is simple, but you can imagine a similar operation in a large codebase.

Misconceptions about types

When you hear the word "strongly typed," it is easy to think that you need to put types everywhere, like in old (before type inference, more on that later) C# or Java code:

IDictionary<int, Car> carsById = new Dictionary<int, Car>(); 

Lots of noise without much benefit.

TypeScript has a feature called type inference; when I type

let name = "tatu"
name = 2; // an error

I don't have to explicitly say that name is a type of String: it can be inferred.

There is also a feature called Contextual Type. Here is an example from the documentation:

window.onmousedown = function(mouseEvent) {
  console.log(mouseEvent.buton);  //<- Error
};

MouseEvent doesn't have a type defined, but TypeScript can still throw an error when MouseEvent doesn't have a property called button. How is this possible?

TypeScript knows that the callback on onmousedown should be a function that accepts a type of MouseEvent. MouseEvent's type doesn't have the property button. This kind of check will save time without any effort from the developer!

Using TypeScript with other tools

When I think about other tools that I have used for JavaScript development, the following come to my mind: linting tools, Browserify/Webpack, testing frameworks, and BabelJS. Is TypeScript making some of them obsolete?

Linting tools

If TypeScript is so powerful when it comes to catching errors, do we need tools like ESLint or JSHint? The answer is "yes." For example, in addition to error checks, ESLint contains stylistic and best practice code format checks. Unfortunately, compatibility with ESLint relies on the TypeScript ESLint Parser project, which is in the experimental stage.

The good news is that there is a tool called TSLint that was created for TypeScript.

Browserify/Webpack

TypeScript is not a bundling tool. For example, if you have your own code in TypeScript and you're using the lodash 3rd party library in the browser, TypeScript won't fetch lodash for you to bundle it into a single file. Bundling is the purpose of Browserify/Webpack.

Testing frameworks

I have written tests in TypeScript, compiled to JavaScript, and then used Mocha, for example, to run tests. I would like to hear your thoughts on this.

BabelJS

Can we ditch BabelJS since TypeScript supports ES2016 features? The answer is: it depends. I asked wiser people what benefits BabelJS provide:

@_Tx3 TypeScript can�t currently compile async/await to ES5. If you need that, you need Babel or something else.— Tero Parviainen (@teropa) May 20, 2016

Embedded JavaScript

In other words, TypeScript supports async/await, but can't compile it to the ECMAScript version that all browsers understand.

If you don't use that feature, then please feel free to remove BabelJS from your build process.

Update: Reader, Birk Skyum, pointed out that support for ES3 compilation is on the roadmap and it will be released on the version 2.0.

When to use TypeScript

Almost every TypeScript blog post mentions that TypeScript is meant for large projects. From Anders Hejlsberg's interview on JavaScript Jabber (30:50):

If you're writing five lines of code, it is probably not worth of the effort ... the larger the project gets, the more valuable it is. Like I said earlier, by the time you get to a couple of thousand lines of code, it's a slam dunk*.

* I had to Google "slam dunk." It seems to be a basketball term for an easy shot, one that is difficult to miss.

Conclusion

Hopefully, I was able to give you at least a little of my enthusiasm so that you will give TypeScript another chance. I would like to hear whether you have had success or miserable experiences using TypeScript in a real project. Until next time!

Discuss on Hacker News