Early Impressions of TypeScript

I've been playing around with TypeScript for several weeks now and, overall, my early impressions are quite favorable. The typing system and its integration with Visual Studio are very nice and seem quite natural to me after working with C# for the last several years. I also like that it produces plain JavaScript as output. I believe this makes more sense than something like Google's Dart because I simply don't believe anything is going to dethrone JavaScript as the top language for web development even if that language provides a superior programming model (see Silverlight). That said I do have a couple of issues with TypeScript.

My first issue isn't with TypeScript proper but with the Visual Studio tooling. When it was originally release TypeScript files appeared in the Solution Explorer with an expandable node which nested the generated .js file under its .ts file. At any time you could easily view the JavaScript code that was being generated by opening the .js file directly from Solution Explorer. Now (at least in Visual Studio 2013) there's no such expansion on the .ts files. The generated .js files are still located in the project but to see them you have to manually open them. Not a major issue but it makes opening the .js file much more cumbersome.

The second issue I've come across I find much more annoying. One of the TypeScript settings in Visual Studio is to combine JavaScript output to a single file. This is a tremendously helpful setting allowing you to code in small independent files but maintain a single reference listing in you HTML page. The problem comes when you try to break class definitions that belong in the same module into separate files. Take the following TypeScript code:

module TheModule {  
    export class FirstClass {} 
    export class SecondClass {} 
}

This code produces the following JavaScript:

var TheModule;  
(function (TheModule) { 
    var FirstClass = (function () { 
        function FirstClass() { 
        } 
        return FirstClass; 
    })(); 
    TheModule.FirstClass = FirstClass; 
    var SecondClass = (function () { 
        function SecondClass() { 
    }
        return SecondClass; 
    })(); 
    TheModule.SecondClass = SecondClass; 
})(TheModule || (TheModule = {}));

All well and good. Some pretty clean JavaScript with nice function closure.

Now, imagine that FirstClass and SecondClass actually have a number of members. Naturally you might be inclined to move each of these classes into its own .ts file for organizational purposes, i.e. FirstClass.ts and SecondClass.ts.

// FirstClass.ts 
module TheModule {  
    export class FirstClass {} 
} 

// SecondClass.ts 
module TheModule {  
    export class SecondClass {} 
}

Great! Until you look at the output code in your single .js file:

var TheModule;  
(function (TheModule) { 
    var FirstClass = (function () { 
        function FirstClass() { 
        } 
        return FirstClass; 
    })(); 
    TheModule.FirstClass = FirstClass; 
})(TheModule || (TheModule = {})); 
var TheModule;  
(function (TheModule) { 
    var SecondClass = (function () { 
        function SecondClass() { 
        } 
        return SecondClass; 
    })(); 
    TheModule.SecondClass = SecondClass; 
})(TheModule || (TheModule = {}));

Houston we have a problem!

There seems to be quite a bit of online debate about whether this output is desirable or not. Most of the arguments for this being correct seem to revolve around the intent of "modules" in the as-yet unreleased Ecmascript 6 which the TypeScript team is trying to align with. The gist of the argument for this output seems to be that if you have a module definition (open and closed curly braces) this is where the closure should occur to deal with the possibility of things like member name collisions that happen if you try to "merge" two module definitions into one file. I understand these arguments but looking at the code above it seems fairly clear that the intent of the code in the two file example was to replicate the code you'd get in the single file example. It's hard for me to imagine a case where one would intentionally define two separate modules with the exact same name. It seems like it would be a better standard, at least when compiling output to a single JavaScript file, to merge like-named modules into one and throw compile errors if name collisions are encountered. One poster in the previously linked debate proposed a "partial" keyword for module to handle this. That certainly seems like it would satisfy both sides but I haven't found any other references to this idea.