I have been using TypeScript for a while now. From 0.7 to 1.0 it changed quite a lot but I think what we have now is a stable language spec. In this post I will explore what TypeScript brings to the table over JavaScript.
In this post I list some general observations regarding TypeScript that I’ve found interesting and/or important to know. I skip showing/explaining the actual syntax and patterns of the language. There is a good guide for that.
What is TypeScript in a few words?
Syntax sugar and wrapper around common JavaScript patterns for better readability (classes, arrow functions) + module system(for namespaces or AMD/CommonJs modules) + static typing system + powerful, type-aware tooling = Amazing developer experience. At least that’s my take on it.
Superset of JavaScript
TypeScript is a superset of JavaScript. What this means is that you can take any existing JavaScript code and it already is valid TypeScript. Or at least the TypeScript compiler will eat it. This is an important fact and means that all existing JavaScript libraries will work fine with your TypeScript code.
Attempts to be future-proof
The added TypeScript syntax is intentionally based on specs/drafs of the future JavaScript. The intention is to bring features of the JavaScript of the future to the present. For example TypeScript implements keywords/constructs like class, extends, super, lambda functions and rest parameters which are all in ES6 specs. Modules are not yet clearly specified in ES6 but are implemented in TS. Yield and generators are not yet implemented in TS but the roadmap for v 2.0 is to align it closely with ES6.
Compiles to idiomatic javascript
The TypeScript compiler produces very clean JavaScript. In fact the output JavaScript looks so natural and clean to me that I can write TypeScript code and then debug and step through the generated JavaScript code with ease.
Open source
Open source and Microsoft… I know, smells fishy, but the typescript compiler really is open source. This means that anyone can fork the compiler and that there is no excuse for editors not to support it. Also, the main repo, which is owned by Microsoft is, as of version 1.0, accepting pull requests.
Editors
Support for TypeScript in Visual Studio is of course, first class. However, other editors are catching up. The TypeScript Playground editor is very good, I would say it is as good as Visual Studio and even better because it supports writing JSDoc comments while Visual Studio does not (even with Web Essentials). However, it is impossible to do serious, multi-file development through the web editor. For non-Windows users I would recommend Eclipse with Palantir plugin because it has good support for intellisense and refactoring as well. There are many IDE’s out there which are working on TypeScript support, but are not just there yet. WebStorm, CATS, Brackets with brackets-typescript, Cloud9 and more.
##Type system TypeScript’s core feature is its optional typing system. When you add type annotations to your code, you get a powerful compile-time type-checking system which validates your code and disappears at runtime, leaving you with pure JavaScript.
Although it might not seem at first glance, TypeScript’s type system is quite interesting and novel. It is not yet-another-typed-language that compiles to JavaScript because it allows us to use types only when we want to. Traditionally in a programming language you either have types or you don’t. However, in TypesScript they are optional and you can use them only in parts of your code. This is great for old code compatibility. For example you may leave the old JavaScript code untyped but add static typing to new code that you write.
TypeScript has a structural typing system which is basically duck typing at compile time (instead of runtime). In duck typing it is said that if an object quacks like a duck and looks like a duck then it is a Duck.
What this means is that interfaces and classes are compared based on their structure and not their identity like for example in C#.
Here is an example that demonstrates this: TypeScript Playground link
Type inference
The type checker is very smart and will infer types whenever it can. In practice this means that you have to add only few type annotations to get useful, type-enhanced code. Sometimes the typescript compiler is able to infer types just from the definition of a variable. And these types will flow through your code via the inference mechanism. Let’s take a look at this example which is pure JavaScript:
var cities = ['New York', 'London', 'Paris'];
var n = cities.map(function(c){return c.length}):
At the same time if you feed this to the TypeScript compiler, it will be able to infer a bunch of things.
In the first line, it will see that the variable ‘cities’ is being defining as an array which contains only string literals and will thus treat it as a variable of type array of strings (string[]).
In the second line it will see a new variable named ‘n’ which stores whatever the .map call on cities returns. It will thus take a look if it can infer anything about that map method. And indeed it can. It knows that cities is an array of strings but it also knows all methods and their type signatures that are defined on an array, including map’s.
And so it will infer that the parameter of the callback function passed to the map method has to be of type string, since the array only contains strings. And it will see that the callback returns the length of that string (a number). It will finally conclude, that the map call will return an array of numbers which will be assigned to ‘n’. ‘n’ is thus of type array of numbers (number[]).
And indeed, , we get confirmation of this:
As a consequence we get full intellisense on the elements of array ‘n’ as can be seen in the image below:
Now that’s quite an enhancement for zero work. What we gain in this small example is intellisense on all variables and type safety. The compiler will warn us if we try to use a type in an incorrect way (but still compile the code to JavaScript).
Conclusion
All in all I would say that TypesCript implements the correct features to enable large scale application managability. The most important part is the compile time type checker and the incredible tooling that is possible to implement on its shoulders (eg. code refactoring, intellisense).
There are a few quirks with the type system which are rare but can and will give you a headache if you ever stumble upon them. Also the modules system looks promising but there are some scenarios with node.js modules, where it gets tricky to integrate JavaScript modules with TypeScript ones seamlessly. I will cover both these areas in a futue post.