The obligatory TypeScript reaction post

It’s been known for some time that Anders Hejlsberg was doing something interesting in the JavaScript space, and when Anders is doing something interesting, it’s worth paying attention. This is, after all, the man who got Real Programmers to use Pascal, and pulled off C++++ (put two of the +’s over the other two: #! See what they did there?). Today the covers were taken off the latest project by the man himself in this Channel 9 video, and it’s TypeScript: “a strict superset of JavaScript that compiles to plain JavaScript”. What “strict superset” means is that all the valid JavaScript that already exists is also valid TypeScript; it’s like the relationship between C++ and C.

Comparisons

TypeScript sits in a similar sort of space to other languages which exist purely to be compiled to JavaScript, such as CoffeeScript, but is different in that it extends its target language instead of replacing it with an entirely different syntax. It’s even more different to cross-language compilers like Script# or ClojureScript, which take an entirely different language originally intended for an entirely different purpose and runtime, and hammer it into JavaScript submission. And it’s not a unilateral attempt to replace JavaScript like Google’s Dart, which also compiles to JS, but is primarily intended to have its own virtual machine runtime; somehow I can’t see the other browser developers implementing Dart VMs any time soon. In some ways that’s a pity, because Dart’s VM is much better than even the best JavaScript implementation, and I do agree with some of the comments that I’ve seen saying that a combined effort to implement a bytecode-based common VM across all browsers would be a better use of everybody’s time, but pragmatically speaking, that just isn’t going to happen.

A language of two halves

There are two main facets to TypeScript. Firstly, and seemingly most important to Anders, it introduces static typing as a language extension. Secondly, it provides a class-based object-oriented programming model that is more palatable to C#, C++ and Java developers than JavaScript’s own prototype-based model.

Static typing

TypeScript applies static typing using a post-fix syntax similar to that in Rust and Go. The type comes after the variable name, like this:

function add(a: number, b: number) {
    return a + b;
}

That’s a little jarring if you’re used to C-style syntax, but as discussed here the post-fix annotation style works better when the “: T” is optional, which it is.

Adding static typing to a method like the above gives several benefits. It means the compiler can check all calls to the add method and ensure that they all pass numbers, and not strings, or teapots. It also means that the return type of the function can be inferred, so a call to it like this:

var sum = add(40, 1);

is able to statically-type the variable sum to number as well.

TypeScript also adds interfaces as a first-class language construct. These are different from classes, which are discussed below, because an object must specifically be an instance of a class, but it can simply implement one or more interfaces. An interface is declared and used like this:

interface Rectangle {
    width: number;
    height: number;
}

function calculateArea(rectangle: Rectangle) {
    return rectangle.width * rectangle.height;
}

The great thing about TypeScript’s interface implementation is that it’s a structural type system: an object doesn’t need to explicitly state that it implements an interface, it just needs to match the interface’s definition. (Structural typing can be found in Go and OCaml, among other languages.) That means that the following is a valid call:

var rect = {width: 10, height: 20};
var area = calculateArea(rect);

The compiler is quite happy with that, because it can check that the untyped object literal in rect has the required width and height properties and they are of the correct type, so that means it implements the interface. Nice, easy and non-invasive.

Explicit type declarations and interfaces make better tooling support possible. The most obvious example is code completion (e.g. IntelliSense), which, for dynamically-typed languages, ranges from difficult to impossible to implement effectively. It’s possible to do some static code analysis and work out what some variables are going to contain at some points in the program flow, but it’s impossible to be certain what type a function argument is going to have. Giving the programmer the ability to say “element is a DOM Element” lets your editor know exactly what methods and properties are available on element, and what signatures and types those methods and properties have.

Static typing also enables more complex code-aware operations like refactoring; if a member is declared by a class or interface, and it’s possible to find all uses of that class or interface in code, then consistently renaming that member becomes possible. Of course, it’s still not going to be able to catch all cases; for example, if, in the code above, you refactored the names of the width and height properties in the Rectangle interface, the change would be applied in the calculateArea function, but not to the object literal declaration. The first you’d hear about that would be from the compiler, complaining that it didn’t match the interface declaration.

It should be noted that modern IDEs, including Visual Studio and JetBrains’ JavaScript-aware editors like WebStorm, do support both code-completion and refactoring, and they do a damn fine job of it, all things considered. But it’s far from perfect, and with TypeScript, it can be a hell of a lot better.

The other really neat trick that TypeScript’s static typing implementation can do is external type declarations. Existing JavaScript libraries can be made to appear statically-typed with a definition file, which work a lot like header files in C and C++; they just contain function signatures and interface and class declarations which match the pre-existing implementation code. At the moment, TypeScript has comprehensive type declaration files for jQuery, jQuery UI, Node.js (plus several common packages, such as Express), and WinRT and WinJS for Windows Store app development. The WinRT case is particularly interesting, because its 18,000 lines of declarations expose TypeScript-compatible information for code that isn’t even written in JavaScript. Also, in the Samples, one of the examples is an implementation of TodoMVC with Backbone.js, which includes type declarations for some of the Backbone framework and shows just how easy it is to add the information yourself if you want to.

Classy code

The second feature that TypeScript brings to the table is class-based object-oriented programming. This is a much easier approach to OOP than prototypal inheritance, particularly when declaring complex class hierarchies with inheritance and whatnot. Here’s one of my least favourite examples of a class hierarchy (my only excuse is that it’s just gone midnight and it’s been a long day):

class Animal {
    private sound: string;
    constructor(sound: string){
        this.sound = sound;
    }
    talk() {
        return this.sound + "!";
    }
}

class Dog extends Animal {
    constructor(){
        super("Woof");
    }
}

(Incidentally, when I typed that code into the online TypeScript Playground, I actually got red squigglies telling me that the Dog constructor needed to call the super (i.e. base) constructor, which was very helpful.)

That fairly simple code compiles to this JavaScript:

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
}
var Animal = (function () {
    function Animal(sound) {
        this.sound = sound;
    }
    Animal.prototype.talk = function () {
        return this.sound + "!";
    };
    return Animal;
})();
var Dog = (function (_super) {
    __extends(Dog, _super);
    function Dog() {
        _super.call(this, "Woof");
    }
    return Dog;
})(Animal);

Now, to be fair, that’s not idiomatic JavaScript code as it would be written by a developer, but the class-based syntax is definitely simpler. Also, the introduction of the visibility-modifier keywords like private means that any code completion can hide inaccessible members, and the compiler can enforce the visibility rules, which is just not possible in JavaScript.

It’s incredibly important to point out here that Microsoft is not, in this instance, going out by itself and randomly adding its own ideas to the language; TypeScript’s class syntax is an implementation of the class syntax proposed for ECMAScript Harmony (ES6). That’s a really big deal, because it means that when ES6 is generally available, TypeScript can simply stop compiling classes. I don’t know if the team are planning on implementing more of the ES6 proposals in this way, but I hope they are considering it.

TypeScript also includes syntactic sugar for modules, and again, this is a positive move by Microsoft. In C# and C++ code is organised into namespaces, and they could easily have brought that paradigm into TypeScript, but instead, they’ve embraced the module approach already favoured by JavaScript. In fact, TypeScript can compile modules in multiple ways, from the regular JavaScript pattern to various dynamic-loading modules such as the CommonJS Asynchronous Module Definition (AMD) system.

Things I like about TypeScript

  • I really like the fact that it’s a superset of JavaScript, that Anders and his team have extended the language rather than creating a complete replacement. It’s going to make it easier for teams to adopt the language, since it’s very readable to existing JavaScript developers. Supporting plain, undecorated JavaScript code also means that working from examples is a lot easier. And it may ameliorate the problems that CoffeeScript developers have when they post their code on Stack Overflow or elsewhere, and find that the JavaScript gurus either can’t or won’t engage with them.
  • Wherever possible, it does type inference, meaning that in a lot of places you can have plain JavaScript but the compiler and tools still know what type a variable is holding.
  • Structural typing for interfaces. I really wish C# could do that.
  • Adding a compile cycle to the development workflow gives you an extra place to catch coding mistakes, and adding static typing on top of that provides even more checking and useful compiler errors.
  • It’s open source, under the Apache 2.0 license, and they’re using Git on Codeplex so you can fork it easily.
  • It’s already self-hosting; the TypeScript compiler is written in TypeScript and compiled to JavaScript using itself (which is a sod to get to and meant somebody had to write a compiler in some other language, which then got thrown away).
  • It’s available through npm, the Node.js package manager, to be run as a command-line tool, so it works on Mac and Linux. There’s also a Visual Studio 2012 extension.
  • The class syntax complies with the ECMAScript Harmony proposal, so it should be future-proof.
  • There are packages or add-ins for Sublime Text 2, Vim and Emacs, although those only provide syntax-highlighting at present.
  • The external type declaration files mean lots of potential for TypeScript to work with the enormous range of JavaScript libraries and frameworks that are out there. I’m hoping somebody will create one for AngularJS.
  • There’s a playground where you can enter TypeScript on one side and see live-compiled JavaScript on the other.
  • There’s a good set of samples, showing TypeScript being used for browser code, Node.js server code and Windows Store apps.
  • I’m a big advocate of the JavaScript/HTML/CSS model for developing Windows Store apps, but at the moment I’m using a hybrid approach, with C# for the complex logic code. TypeScript has the potential to negate that need entirely.

Things I don’t like about TypeScript

  • I’m not entirely convinced by the full-on language support for type declaration. In the video, Anders tries to explain why they didn’t go with a comment-based system similar to those in some existing compilers, but I’m not sure I really followed it. Given that most of the other features are an ahead-of-time implementation of ECMAScript Harmony proposals, it seems like the typing is the only thing that makes TypeScript a language and not a compiler along the lines of Traceur. That said, I haven’t read the specification yet, so I might be missing something.
  • Classes can’t explicitly implement interfaces. That complaint entirely flies in the face of the previous point, but if it’s going to be a whole language, then why not push things a bit further. If classes could implement interfaces, then there’d be even more compile-time checking and refactoring could go a little further.
    My bad, classes can implement interfaces. Thanks to Guillaume Lecomte for pointing that out.
  • There’s some kind of magic going on in Visual Studio 2012 around compilation of TypeScript files, and there doesn’t seem to be a TypeScript item template in the Add New Item dialog for web or Windows Store projects.

Things I would like to see in TypeScript

  • Something like C# 5’s async/await keywords. One of the major causes of hard-to-maintain, spaghetti JavaScript is the callback pattern for asynchronous programming, and JavaScript is all about asynchronous programming. Promise-style systems like Q make life a little better, but proper syntactic sugar would be awesome.
  • Tuples and destructuring. I just like tuples and destructuring (where a tuple can be simply assigned to two or more variables in a single language construct).
  • A more complete non-Visual Studio tooling story. At the moment, only syntax highlighting is available as a plug-in for the main three text editors; some refactoring support and real-time error highlighting would also be useful. Also, packages for other IDEs like MonoDevelop, JetBrains WebStorm/PhpStorm/RubyMine, or Eclipse, will help to drive adoption. As Miguel de Icaza notes in his blog post, an awful lot of (most?) JavaScript is written by non-Windows users.
  • Source maps, so you can step-debug through the code you’ve written instead of the code the compiler has generated.
    Update:There is experimental support for source maps, if you pass –sourcemap to tcs on the command line. Hat-tip to minamo for pointing that out.

Comments

  1. If we’re to be picky, C++ is not a strict superset of C.

  2. Guillaume L. says:

    It’s funny I just read this article with your comment wishing that Google had just use ES6 specs for Dart: http://lostechies.com/jimmybogard/2011/10/12/the-dart-hello-world/
    Looks like microsoft nailed it.

    Big +1 for the tooling on other platforms request

  3. You can already remove one bad point: Actually classes can implement interfaces using the implements keyword: https://gist.github.com/3818003

  4. A very good summary post for advanced developers! Let’s just hope that Microsoft hate doesn’t kill a good attempt.

    Next… how to get rid of curly brackets and semicolons. Looking forward for CoffeeType…

  5. Good read, and a nice way to see all the various JS-related languages in context.
    By the way, at the end of the second paragraph you mention “and I do agree with some of the comments that I’ve seen saying that a combined effort to implement a bytecode-based common VM across all browsers would be a better use of everybody’s time”.
    If only the Flash plugin would have had fast DOM-control, we would have been there already :-)

  6. Re: classes – one of the problems is that ES6 doesn’t seem to have a single ‘class’ standard. I haven’t gone that deep into the proposal, but TypeScript seems to use the “Minimal classes” proposal (http://wiki.ecmascript.org/doku.php?id=strawman:minimal_classes) not the main class one.

    How final is Harmony’s proposal? It seems to be difficult to find information on that. I hope Microsoft is not creating a new JScript.

  7. Actually, on second thought, TypeScript seems to use the “Maximally Minimal” proposal instead (http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes).

  8. To comment on one of your bad points, it looks like the item template only shows up for Web Application Projects of the C# variety. It doesn’t show for websites, or VB WAPs currently.

  9. I really like this article! I used your interface example in my post @ http://coderwall.com/p/gicwwq

    Thanks for that.

  10. I truely hope that this is a new beginning. Good work again, Hejslberg!

  11. Andreas Kastirke-Richter says:

    “there doesn’t seem to be a TypeScript item template in the Add New Item dialog for web or Windows Store projects.”
    The template is not located in the web-folder, but in the overlying Visual C# folder (have ot checked Windows Store projects).
    Typescript even works with my visual studio 2012 web express version.

  12. I second your call for async/await support! That would finally make JavaScript palatable.

  13. +1 for Tuples and destructuring!

  14. WoundedEgo says:

    Very helpful post, thanks!

  15. Great post, thanks.

  16. here the future of js
    JS->typeScript->JS2 just like Flash AS1->AS2->AS3 ;)
    AS2/TypeScript is just a layer over AS1/JS

    • Finally some sanity. For years it feels like we’re delayed-re-evolving the same thing Flash and AIR had for years now. Bummer Adobe has bad rep but AS3 is great.

    • You can’t write AS3 and then run it anywhere that JS currently works. That’s one good reason why AS3 is a dead-end and TypeScript might succeed. Back in the late 80′s IBM came out with OS/2 and Microsoft came out with Windows. OS/2 was much better than Windows, but you had to switch to OS/2 vs. Windows which could run on top of DOS, but only when you needed it. Those who are unfamiliar with history are doomed to repeat it.

  17. Great overview! Thanks a lot. I think TypeScript looks awesome and suits me a lot better than CoffeeScript.

  18. Have you ever looked into Flash’s ActionScript? TypeScript feels a lot like ActionScript 2.0, which was a syntax sauce on AS1 which was EmcaScript same as javascript.

    ActionScript 3.0 is what you’ll like for sweetspot between scripting and programming with the access modifiers and proper compiler.

  19. I can’t figure out why the typing syntax is in Pascal-style instead of the C / C++ / C# / Java-style. I mean why we have add(a: number, b: number) instead of add(number a, number b). Why a C# developer needs to exchange the order of type / name in the parameters? When I write VB.NET or Pascal I always interchange the type and name of the parameters and this brings unnecessary confusion.

    • Because “: ” is easier to implement as optional in the language.

      As an aside my guess is that most Javascript developers across the world are not C / C++ / C# / Java developers, they are HTML / CSS / PHP / Ruby / Python / etc. developers.

      Me? I prefer Pascal style, always have.

  20. > The obligatory TypeScript reaction post
    The best such post yet.

  21. RE: “◾There’s some kind of magic going on in Visual Studio 2012 around compilation of TypeScript files, and there doesn’t seem to be a TypeScript item template in the Add New Item dialog for web or Windows Store projects” – You’re absolutely correct. The compilation process in Visual Studio is extremely bad for Website projects, the .ts files won’t compile, no matter which way you try to compile them. You end up having to manually drop the ts files onto the compiler’s exe to get them compiled everytime you want to debug your page! And what’s worse, Web Essentials, VS File Extension installer; they don’t work either for a lot of people. The only way to get them to auto-compile is to paste some XML stuff in the project file – but that’s not possible for most people because project files are only applicable to Projects – not Website projects. So, I want to help people out here by giving them some relief if they’re also experiencing compilation issues. I wrote a simple app that sends your ts files as parameters to the compiler for you: http://onthefly.codeplex.com/

  22. No wonder people say that computers are taking over the world.I’m very glad to hear that.She mended the broken doll.Many people prefer living in the country to living in the town.How much does it cost? The editor over looked a print error.The editor over looked a print error.I’ll try my best.He is the happiest man alive.I’m an office worker

  23. Since JavaScript has tuples (as arrays), and has destructuring assignment (again utilizing arrays)… and since TypeScript is a superset of JavaScript… doesn’t TypeScript have tuples and destructuring?

    And don’t devalue the 0-tuple (the null-tuple; the empty set… the unit type; null (not to be misconstrued with the C/C++ null-pointer)) and 1-tuple (singleton)! They are at least as valuable — and perhaps moreso — as 2-tuple (ordered-pair), 3-tuple (triplet), and tuples of greater cardinality.

  24. myschizobuddy says:

    “TypeScript compiler is written in TypeScript and compiled to JavaScript using itself”
    I never understood how this is done?

Trackbacks

  1. [...] The obligatory TypeScript reaction post – Mark Rendle [...]

  2. [...] The obligatory TypeScript reaction post (Mark Rendle) [...]

  3. [...] from the ECMAScript 6 (“Harmony”) proposals. It has the pedigree to be great – as Mark Rendle said: It’s been known for some time that Anders Hejlsberg was doing something interesting in the [...]

  4. [...] http://blog.markrendle.net/2012/10/02/the-obligatory-typescript-reaction-post/ Rate this:Like this:LikeBe the first to like this. This entry was posted in Consultancy, Development, JavaScript, Technical and tagged FormScripting, Javascript, typescript. Bookmark the permalink. ← The Customer in CRM – Going Social? [...]

  5. [...] bereits nach ECMAScript 6 Spezifikation. Einen sehr guten Artikel als Übersicht findet ihr hier. Und wenn ihr in Zukunft TypeScript-Support in WebStorm haben möchtet, solltet ihr hier einen [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 4,004 other followers

%d bloggers like this: