Общо показвания

октомври 04, 2012

TypeScript (by Microsoft)

The last few days the news was all over the Internet: Microsoft has released a preview of a new superset of JavaScript.

I decided that I should give it a try, especially after reading materials on the internal situation in Microsoft vs. the same in Google. It is not a secret, that I have not been using Microsoft technologies for 12-13 years. What good comes out of Redmond, right? Or at least that is the mantra most of Linux and OSX users swear by.

Well, it turns out Microsoft have learned and they are indeed able to produce high quality. I have talked previously about the TV interface and the fact that is uses no library at all and uses everything available in webkit. Well it turns out it works without any changes in Internet Explorer 10! So yeah, tehy have learned!

Now about the new language.

The last few months I have been working extensively with closure tools and I can honestly say that while it is very interesting and big and well designed product, it is a subset of the original language in so many ways, that it is like you have to learn to think in javascript anew.  It dictates memory saving rules and design patterns, but on top of that it dictates constructs that a very small minority of JavaScript developers would appreciate. Its pluses and minuses are not the topic here, however I will use it to compare to TypeScript.

The history, the aims and directions for the language you can get from the official web site and slightly reinterpreted from all news about it. Here I will be talking more about it from developer's point of view.

First of all, it provides the class, interface and module constructs on top of a type system. Nothing new here, however the module system seem to confuse most of the developers, judging from the forums. The beauty I see in it is that it can output modules in both commonJS and AMD format. This means that you can indeed write your logic once and make it work in node and browser without using any wrapping or boilerplate code! This is really really great. I have read about similar capabilities, but most of the time it was converting from one to the other or involved writing boilerplate code.

The module pattern TypeScript authors decided to use is a well known and kind of "used and dismissed" one: self invoking function wrapping. The reason it is not widely used I believe is that it leaves the developer managing dependencies manually. There was no sane way to manage a project with hundreds of files this way.

TypeScript uses something called references: a comment at the top of the source file that declares dependencies. The declaration has two uses: 1) it allows the editor (I will talk about editor support later) to know which files to use for completion/type checking and if "output all" mode is used, those files fill be included in the build. The later will produce a single javascript file with optional source map that has the sources arranged in the correct order. This way it is able to provide a build system on its own, without depending on AMD loader.

Unfortunately most of the code out there is written using different patterns (which is why writing large application trying to compile a working system out of so many different pieces is pain in the *ss). The interesting thing about TypeScript is that is is compatible with any library because the resulting javascript is "pure" javascript. It does not expect anything from any other part of your application. You can write any code in TypeScript that depend on backbone for example. The type system can be 'boosted' much like the closure compiler type system. You just define an interface and then declare a variable that is using it. Let's see an example. In most modern browsers on the Element class you have classList property that is an object with property length and a few methods. It is not included in the lib.d.ts file (d.ts files are the way TypeScript can include type declarations only without actual implementations, much like the extern files in closure).

interface classList {
  length: number;
  contains(classname: string): bool;
  add(classname: string): void;
  item(index: number): string;
  remove(classname: string): void;
  toggle(classname: string): void;
}

interface Element {
  classList: classList;
}
This will tell the editor and the compiler about a property on all Element instances, named classList which implements the classList interface. The interface is not really defined in the browsers as I defined it here, in fact it is a DOMTokenList and one could simply complete the Element interface with classList as this:

interface Element {
  classList: DOMTokenList;
}

but I am using this as an example how one can define an interface and then attach it to an existing interface. This is possible because the interfaces are 'open' as they call them in TypeScript, which means that one can add to them from wherever needed.

If you happen to override an interface property you will get a warning.

As this simplified example shows, one can easily add types for an existing code base and then include it. In case this is done and a '*.d.ts' is included in a source file it will be considered for types but as it does not provide implementation the developer has to provide it manually (in the browser - include the javascript for the external source for example). However this covers a large portions of the web sites in the wild!

A few words about the editors. Syntax highlighting is provided for vim, emacs and Sublime Text 2. I have not tried it in vim and I have never used emacs, however sublime is working (only in OSX, interestingly it is not working under Linux, on the sublime text 2 forums there are other people with the same issue). There is already a gist providing build config for ts files in sublime text 2. I have tested this one as well, however the line/column error recognition is not working, but the build is working okay. On the demo video, presenting the language, a plugin for VisualStudio is used. If you happen to have Window 7/8 and VisualStudio, the plugin is free of charge and is working as demonstrated, meaning - it works great! Auto completion, error detection and intellisense are all great. What you might have not noticed however is that the same is available in the play ground on the website! Which means that all this intellisense, type and error checking etc is running on javascript. Hopefully it will be available soon on other editors/ides as well.

I want to say something here as well: Cloud9 IDE were the first one to congratulate themselves with "support for the language". However having syntax highlighting in the editor is not exactly language support. It would be great if they could have had the intellisense (as it was already demonstrated that it could run on javascript only) and then go out loud. Never the less, I hope they will catch up on this. They have built great platform and I think this will be a great completion to the product.

Part two will cover commonJS and AMD modules.


Няма коментари: