Microsoft's TypeScript may be providing several exciting ECMAScript 6 features early, but its type system makes a wide array of common JavaScript patterns exceedingly difficult to implement. Here are some examples I ran into while developing a custom business application: ---- '''Singletons''' It's very easy to implement a singleton in JavaScript. Here's how you'd do it in a CommonJS module: function Db() { // make methods, etc., in here } module.exports = new Db(); // then to use it elsewhere in the program: var db = require('db'); No muss, no fuss, no exposed constructor function that lets you break the singleton abstraction and create more instances of the same "class". Now, the equivalent code in TypeScript looks like this: class Db { // make methods, etc., in here } var db = new Db(); export = db; // then to use it elsewhere in the program: import db = require('db'); Slightly less convenient -- TypeScript doesn't let you use arbitrary expressions on "export =" lines -- but who's counting? Now, here's the problem: The type-checker rejects this outright! You won't be allowed to export the singleton, because it's using the "private type" Db. In fact, it's impossible to hide the detail that a class is used to implement the singleton behind-the-scenes, since the type-checker requires you to export the class too. You have to write ''this'': export class Db { // make methods, etc., in here } export var db = new Db(); // then to use it elsewhere in the program: import Db = require('db'); var db = Db.db; Only slightly more verbose, sure, but instantly your abstraction is unavoidably broken. ---- '''Interop with "Extensible" Libraries''' It's a very common JS idiom for a library to permit plugins and extensions by adding an object of your own to one of the library's built-in objects. jQuery does it. Knockout does it. I was using both in my app, and TypeScript hates it. Here's what my Knockout extension looks like: var signatureEmpty = "image/jsignature;base30,"; ko.bindingHandlers.signature = { init: function (el, valueAccessor) { var value = valueAccessor(); $(el).jSignature({ height: 100, width: 400 }); $("") .insertAfter(el) .click(() => $(el).jSignature('clear')); if (ko.unwrap(value)) { ( ko.bindingHandlers.signature.update)(el, valueAccessor); } if (ko.isObservable(value)) { $(el).bind('change', function (e) { value($(e.target).jSignature("getData", "base30")); if (value() === signatureEmpty) value(null); }); } }, update: function (el, valueAccessor) { var value = ko.unwrap(valueAccessor()); if (value && value !== signatureEmpty) { $(el).jSignature("setData", "data:" + value); } } }; Pretty straightforward, idiomatic use of the library. Note that jSignature is a jQuery plugin, so this handily demonstrates the issue for ''both'' libraries. That issue is that TypeScript rejects the above code, both the part assigning to ko.bindingHandlers and the part calling $.fn.jSignature, because its type-checker claims that those objects just don't have those slots (ko.bindingHandlers.signature and $.fn.jSignature respectively). It makes some sense for the jQuery plugin, but absolutely none for the Knockout one: Of ''course'' it doesn't have that slot, because I'm defining it right now! The only way to get this stuff accepted is to add another file to your project called a "TypeScript definitions file", which looks like this (I named it whoinventedthistypesystem.d.ts; this stuff had put me in a bad mood): interface JQuery { jSignature(): void; jSignature(options: any): void; jSignature(command: string, ...options: any[]): any; } // Definition to permit us to define the 'signature' and 'diagram' custom Knockout bindings (the actual // definitions are in the file App/viewmodels/ReportEdit.ts). interface KnockoutBindingHandlers { signature: KnockoutBindingHandler; } With that above definition, TypeScript is placated and accepts the file. ''But'' it's still overly restrictive. Notice the signatureEmpty variable? Initially, I tried to encapsulate that inside the binding definition like so: ko.bindingHandlers.signature = { empty: "image/jsignature;base30,", // methods using it here // accessed as ko.bindingHandlers.signature.empty } But of course that was rejected, because KnockoutBindingHandler objects ''obviously'' don't have a slot called "empty". Basically, TypeScript is seriously inconvenient when it comes to extending libraries. '''Bonus''': See that () thing in my definition of ko.bindingHandlers.signature.init()? That's what it looks like in TypeScript when you cast to any, otherwise known as ''throw away all type information''. Despite the ko.bindingHandlers.signature.update() function, to inspection, clearly having the right type, the type-checker rejected that too until I threw away that information! ---- '''Promises''' TypeScript doesn't understand them. It ''can't''. It's just not expressive enough. Here's an example, taken from the aforementioned Db class: public sync(): Q.Promise { return this.IsAuthenticated().then((result) => { if (result) return this.doSync(); else return this.doLogin(); }); } private doSync(): Q.Promise { return this.manager.saveChanges().then(() => breeze.EntityQuery.from('Report').using(this.manager).execute().then(() => true) ).fail(this.syncFailure.bind(this)); } private syncFailure(message): boolean { return false; } private doLogin(): Q.Promise { return this.Login().then((result) => { if (result) return this.doSync(); else return this.syncFailure('Unable to Login'); }); } This'll be totally rejected by the type-checker! In particular, TypeScript is incapable of comprehending the "flattening" aspect of promises, that being that a "promise for a promise for a value" is exactly the same thing as "a promise for a value". The only way to get this accepted is to ''delete the type signatures''; if you have to delete the typesigs for standard idioms to work, why have a type-checker? -------- I won't speak for SystemsSoftware development. But from an application developer's perspective, you may be expecting/wanting more dynamic abstraction than the industry (typical organizations) wants. But this view repeats the debate in GreatLispWar. -t [This is all from a custom business application, all rooted entirely in idiomatic use of JavaScript tools and libraries such as Knockout, jQuery, and Q (providing the promises). How is it "more dynamic abstraction" than would be wanted, considering nothing I present here is outside the recommended scope of the libraries I'm using? -DavidMcLean] VB, Delphi, etc. rarely needed anything like jQuery because it didn't have a fscked-up DOM. [So? In your opinion, the DOM is messed up. Tools like jQuery and Knockout allow us to manage it in a structured, orderly way. -DavidMcLean] "Structured and orderly" compared to prior browser-based techniques, perhaps, but I see it as a band-aid. I'll agree that initial development in the "static OOP" way may be slow, but it usually made maintenance easier because the compiler would tell you what's missing and where it's missing. I'm actually a fan of GUI's as a service rather than app-language-specific API's, but that's kind of another story. [Honestly, I think the DOM itself is pretty usable these days; standard DOM-manipulation methods like document.querySelectorAll() may not be as concise as jQuery, but "vanilla JS" is ''absolutely'' an effective means for DOM-manip now the APIs are standardised. None of that is the point, however. The point here is that TypeScript's stricter static type system makes simple and wholly idiomatic forms of expression, easy in JavaScript, completely impossible to use. -DavidMcLean] I question whether the NetworkDatabase-like approach of those is the best way to "do queries". Further, power can sometimes be a dangerous thing. Sometimes its really nice to be able to easily do something to every GUI element, but it also means that sub-app A may clobber what sub-app B is trying to do. The DOM is kind of a '''wild-west''' with few rules or regulations. It's great that your cattle can roam free, but it also may means somebody may be pooping in your stream (or what you thought was your stream) without your knowledge. Original coders may love it, but maintenance programmers tend to turn grey over cowboy gui engines/designs. [The way to "do queries", as you put it, is appropriate to the domain; the DOM is a tree, so it's suitable to use selectors geared for expressing tree properties (like the descendant and sibling selectors). As for your "wild-west", why would you have two independent "sub-apps" active on exactly the same document? That's not a sensible design. -DavidMcLean] SeparationOfConcerns. You may want a fancy song player on the left side, and a fancy slide-show on the right side of the screen/page. If there is no reason why they should be linked, then the wall between them should be tall and strong to avoid cross-fudging of each other. [Then put them in