Thoughts on TypeScript
Earlier this week, Microsoft released TypeScript[1], a new compile-to-JavaScript language for “application scale JavaScript.” My initial reaction was confusion:
Um, why? blogs.msdn.com/b/somasegar/ar… (via @izs)
— Nicholas C. Zakas (@slicknet) October 1, 2012
It seems like almost every week there’s a new language that’s trying to replace JavaScript on the web. Google received a lukewarm reception when it introduced Dart[2], it’s own idea for fixing all of JavaScript’s perceived flaws. CoffeeScript[3] continues to be the most prominent of these options, frequently inciting the holy wars online. And now Microsoft is throwing its hat into the ring and I couldn’t help but wonder why.
My bias
Before talking about TypeScript specifically, I want to explain my personal bias so that you can take the rest of my comments in their proper context. There is a very real problem in the web development industry and that problem is a significant lack of good JavaScript developers. I can’t tell you the number of companies that contact me trying to find above-average JavaScript talent to work on their applications. Yes, there are many more competent JavaScript developers now than there were 10 years ago, but the demand has increased in a way that far outpaces the supply increase. There are simply not enough people to fill all of the JavaScript jobs that are available. That’s a problem.
Some would argue that the high demand and low supply puts good JavaScript developers in an awesome position and we should never want to change that. After all, that’s why we can demand the salaries that we do. From a personal economic standpoint, I agree. From the standpoint of wanting to improve the web, I disagree. Yes, I want to be able to make a good living doing what I do, but I also want the web as a whole to continue to grow and get better, and that only happens when we have more competent developers entering the workforce.
I see compile-to-JavaScript languages as a barrier to that goal. We should be convincing more people to learn JavaScript rather than giving them more options to not write JavaScript. I often wonder what would happen if all of the teams and companies who spent time, energy, personnel, and money to develop these alternatives instead used those resources on improving JavaScript and teaching it.
To be clear, I’m not saying that JavaScript is a perfect language and doesn’t have its warts. Every language I’ve ever used has parts that suck and parts that are awesome, and JavaScript is no different. I do believe that JavaScript has to evolve and that necessarily introduces more parts that will suck as well as more parts that are awesome. I just wish we were all spending our efforts in the same area rather than splintering them across different projects.
What is TypeScript?
I spent a lot of time this week looking at TypeScript, reading through the documentation, and watching the video on the site. I was then invited by Rey Bango to meet with a couple members of the TypeScript team to have my own questions answered. With all of that background, I feel like I have a very good idea about what TypeScript is and what it is not.
TypeScript is first and foremost a superset of JavaScript. That means you can write regular JavaScript inside of TypeScript and it is completely valid. TypeScript adds additional features on top of JavaScript that then get converted into ECMAScript 5 compatible code by the TypeScript compiler. This is an interesting approach and one that’s quite different from the other compile-to-JavaScript languages out there. Instead of creating a completely new language with new syntax rules, TypeScript starts with JavaScript and adds additional features that fit in with the syntax quite nicely.
At its most basic, TypeScript allows you to annotate variables, function arguments, and functions with type information. This additional information allows for tools to provide better auto complete and error checking than you could get using normal JavaScript. The syntax is borrowed from the original JavaScript 2/ECMAScript 4 proposal[4] that was also implemented as ActionScript 3:
var myName: string = "Nicholas";
function add(num1: number, num2: number): number {
return num1 + num2;
}
function capitalize(name: string): string {
return name.toUpperCase();
}
The colon syntax may look familiar if you ever used Pascal or Delphi, both of which use the same syntax for indicating the type. The strings, numbers, and booleans in JavaScript are represented in TypeScript as string, number, and bool (note: all lowercase). These annotations help the TypeScript compiler to figure out if you are using correct values. For example, the following would cause a warning:
// warning: add() was defined to accept numbers
var result = add("a", "b");
Since add() was defined to accept numbers, this code causes a warning from the TypeScript compiler.
TypeScript is also smart enough to infer types when there is an assignment. For example, each of these declarations is automatically assigned a type:
var count = 10; // assume ": number"
var name = "Nicholas"; // assume ": string"
var found = false; // assume ": bool"
That means to get some benefit out of TypeScript, you don’t necessarily have to add type annotations everywhere. You can choose not to add type annotations and let the compiler try to figure things out, or you can add a few type annotations to help out.
Perhaps the coolest part of these annotations is the ability to properly annotate callback functions. Suppose you want to run a function on every item in an array, similar to Array.prototype.forEach(). Using JavaScript, you would define something like this:
function doStuffOnItems(array, callback) {
var i = 0,
len = array.length;
while (i < len) {
callback(array[i], i, array);
i++;
}
}
The callback function accepts three arguments, a value, an index, and the array itself. There’s no way to know that aside from reading the code. In TypeScript, you can annotate the function arguments to be more specific:
function doStuffOnItems(array: string[],
callback: (value: string, i: number, array: string[]) => {}) {
var i = 0,
len = array.length;
while (i < len) {
callback(array[i], i, array);
i++;
}
}
This code adds annotations to both arguments of doStuffOnItems(). The first argument is defined as an array of strings, and the second argument is defined as a function accepting three arguments. Note that the format for defining a function type is the ECMAScript 6 fat arrow function syntax.[5] With that in place, the compiler can check to see that a function matches the signature before the code is ever executed.
The type annotations really are the core of TypeScript and what it was designed to do. By having this additional information, editors can be made that not only do type checking of code before its executed, but also provide better autocomplete support as you’re coding. TypeScript already has plug-ins for Visual Studio, Vim, Sublime Text 2, and Emacs,[6] so there are lots of options to try it out.
Additional features
While the main point of TypeScript is to provide some semblance of static typing to JavaScript, it doesn’t stop there. TypeScript also has support for ECMAScript 6 classes[7] and modules[8] (as they are currently defined). That means you can write something like this:
class Rectangle {
constructor(length: number, width: number) {
this.length = length;
this.width = width;
}
area() {
return this.length * this.width;
}
}
And TypeScript converts it into this:
var Rectangle = (function () {
function Rectangle(length, width) {
this.length = length;
this.width = width;
}
Rectangle.prototype.area = function () {
return this.length * this.width;
};
return Rectangle;
})();
Note that the constructor function is created appropriately and the one method is properly placed onto the prototype.
Aside from modules and classes, TypeScript also introduces the ability to define interfaces. Interfaces are not defined in ECMAScript 6 at all but are helpful to TypeScript when it comes to type checking. Since JavaScript code tends to have a large amount of object literals defined, interfaces provide an easy way to validate that the right type of object is being used. For example:
interface Point {
x: number;
y: number;
}
function getDistance(pointA: Point, pointB: Point) {
return Math.sqrt(
Math.pow(pointB.x - pointA.x, 2) +
Math.pow(pointB.y - pointA.y, 2)
);
}
var result = getDistance({ x: -2, y: -3}, { x: -4, y: 4})
In this code, there’s an interface called Point with two properties x and y. The getDistance() function accepts two points and calculates the distance between them. The two arguments can be any object containing exactly those two properties of x and y, meaning I can pass in object literals and TypeScript will check to ensure that they contain the correct properties.
Both interfaces and classes feed into the type system to provide better error checking. Modules are just ways to group related functionality together.
What I like
The more I played with TypeScript the more I found parts of it that I really like. First and foremost, I like that you can write regular JavaScript inside of TypeScript. Microsoft isn’t trying to create a completely new language, they are trying to augment JavaScript in a useful way. I can appreciate that. I also like that the code compiles down into regular JavaScript that actually makes sense. Debugging TypeScript generated code isn’t all that difficult because it uses familiar patterns.
What impressed me the most is what TypeScript doesn’t do. It doesn’t output type checking into your JavaScript code. All of those type annotations and error checking are designed to be used only while you’re developing. The final code doesn’t do any type checking unless you are doing it manually using JavaScript code. Classes and modules get converted into regular JavaScript while interfaces completely disappear. No code for interfaces ever appear in the final JavaScript because they are used purely during development time for type checking and autocomplete purposes.
The editor integration for TypeScript is quite good. All you have to do is add a few annotations and all of a sudden the editor starts to light up with potential errors and suggestions. The ability to explicitly define expectations for callback functions is especially impressive, since that’s the one area I tend see a lot of issues related to passing incorrect values into functions.
I also like that Microsoft open-sourced TypeScript. They seem to be committed to developing this in the open and to developing a community around TypeScript. Whether or not they follow through and actually operate as an open source project is yet to be seen, but they’ve at least taken steps to allow for that possibility.
What I don’t like
While I applaud Microsoft’s decision to use ECMAScript 6 classes, I fear it puts the language in a difficult position. According to the TypeScript team members I spoke with, they’re absolutely planning on staying in sync with ECMAScript 6 syntax for modules and classes. That’s a great approach in theory because it encourages people to learn skills that will be useful in the future. In reality, that’s a difficult proposition because ECMAScript 6 is not yet complete and there is no guarantee that the syntax won’t change again before the specification is finished. That puts the TypeScript team in a very difficult position: continue to update the syntax to reflect the current reality of ECMAScript 6 or lag behind (possibly fork?) In order to keep their development environment stable.
The same goes for the type annotations. While there is significant prior work indicating that the colon syntax will work in JavaScript, there’s no guarantee that it will ever be added to the language. That means what TypeScript is currently doing may end up at odds with what ECMAScript eventually does. That will also lead to a decision as to which way to go.
The TypeScript team is hoping that a community will evolve around the language and tools in order to help inform them of which direction to go when these sort of decisions appear. That’s also a double-edged sword. If they succeed in creating a large community around TypeScript, it’s very likely that the community may decide that they want to go away from the ECMAScript standard rather than stick with it due to the high maintenance cost of upgrading existing code.
And I really don’t like having a primitive type named bool. I already told them I’d like to see that changed to boolean so that it maps back to the values returned from typeof, along with string and number.
Should you use it?
I think TypeScript has a lot of promise but keep one thing in mind: the current offering is an early alpha release. It may not look like that from the website, which is quite polished, or the editor plug-ins, or the fact that the version number is listed as 0.8.0, but I did confirm with the TypeScript team that they consider this a very early experimental release to give developers a preview of what’s coming. That means things may change significantly over the next year before TypeScript stabilizes (probably as ECMAScript 6 stabilizes).
So is it worth using now? I would say only experimentally and to provide feedback to the TypeScript team. If you choose to use TypeScript for your regular work, you do so at your own risk and I highly recommend that you stick to using type annotations and interfaces exclusively because these are removed from compiled code and less likely to change since they are not directly related to ECMAScript 6. I would avoid classes, modules, and anything else that isn’t currently supported in ECMAScript 5.
Conclusion
TypeScript offers something very different from the other compile-to-JavaScript languages in that it starts with JavaScript and adds additional features on top of it. I’m happy that regular JavaScript can be written in TypeScript and still benefit from some of the type checking provided by the TypeScript compiler. That means writing TypeScript can actually help people learn JavaScript, which makes me happy. There’s no doubt that these type annotations can create a better development experience when integrated with editors. Once ECMAScript 6 is finalized, I can see a big use for TypeScript, allowing developers to write ECMAScript 6 code that will still work in browsers that don’t support it natively. We are still a long way from that time, but in the meantime, TypeScript is worth keeping an eye on.
References
- TypeScript (typescriptlang.org)
- Dart (dartlang.org)
- CoffeeScript (coffeescript.org)
- Proposed ECMAScript 4th Edition – Language Overview (ECMA)
- ECMAScript 6 Arrow Function Syntax (ECMA)
- Sublime Text, Vi, Emacs: TypeScript enabled! (MSDN)
- ECMAScript 6 Maximally Minimal Classes (ECMA)
- ECMAScript 6 Modules (ECMA)
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




24 Comments
I read through typescript and watched, and played, and all that stuff.
For now, what I see typescript being able to fill the best is a GOOD documentation standard. It looks to fill those pieces and I’d love to see a good fork that does that.
I like the language, it makes sense, as a JS dev I can write in it, and that’s really what matters. I like that they also shimmed all the type declarations for major API’s (including the dom).
It’s a solid project that, I think, fills a void.
Justin Long on October 4th, 2012 at 11:38 am
Thanks for weighing in with your well-articulated perspective. What are your thoughts on TypeScript’s switch for compiling to either AMD or CommonJS modules?
Oran on October 4th, 2012 at 1:33 pm
I think the most similar product to TypeScript isn’t a JS language, but Google’s Closure compiler. I have relied heavily on the compiler’s markup to improve js code quality. With the creation of TypeScript, I’m thinking it’s a great improvement, since Closure compiler didn’t improve very much over time. I’ll be happy to try it in the future.
Some questions: can it do macro substitution, and omit markup blocks? Can it exclude unreachable code?
I think a good javascript preprocessor is very much needed, and TypeScript might be an excellent one, considering its provenance.
Michael Scholz on October 4th, 2012 at 1:51 pm
@Oran – You’re welcome. I like TypeScript switch for module compilation, it seems like a nice compromise amongst the various module formats that are out there.
Nicholas C. Zakas on October 4th, 2012 at 2:05 pm
@Michael – technically, it does do macro substitution, but I suspect what you mean is can you define your own macros and I believe the answer to that is no. I also don’t believe that it tries to find unreachable code. Once again, keep in mind that TypeScript is very focused on the value of static type checking in JavaScript. If a feature doesn’t relate directly to that, it’s unlikely to make it in.
Nicholas C. Zakas on October 4th, 2012 at 2:07 pm
To get a little bit theoretical, this is almost a foresight to where programming overall is heading. When I was an 8 year old Super Nintendo junkie, I remember hearing my parents complain (after I put away my Sega Genesis), “Why can’t they just make ONE machine that plays ALL of the games? You know they could, they just want you to keep buying these dang machines!” The woman cutting my hair the other day brought up the popular iPhone vs. Droid debate, saying “You know they can just make the app, and have it run on all of the devices. They’re just trying to get you to buy their phones.”
So, what I’m wondering is, shouldn’t this naive, consumer comprehension be a good-for-everyone reality? Could we be headed towards this sort of unison? Ten or fifteen years from now, are we writing in ES8, hoping that ES7 is widely enough supported in older browsers?
My guess is that our mornings as “developers” begin by opening an application on our device called “App Maker.” And maybe that “App Maker” app (which I hope is given a more creative name) allows us to choose “JavaScript syntax,” or “Python syntax,” or whatever it may be. Maybe there is no code in the way that we know it. Optimization and advanced algorithmic sorts can be taken for granted, letting us get by with a kid-friendly, graphical UI, that beneath the surface is churning out only the most beautiful and efficient code.
I thoroughly enjoy the definition of programming now and take every opportunity to soak up all the information I can about JavaScript, including posts like this and your CS series. However, all of us developers are pretty smart people whose brains require the absorption and retention of new information on a daily basis. So let’s think realistically about where we need to be in the future before we settle for just patching the way things are now.
With all of this bending and molding of the language (CoffeeScript, TypeScript, Dart, etc), we’re easing our minds into the concept of creating our products in the way that’s comfortable for ourselves. As uncertain as the faster-and-faster pace of technology development leaves us, we can at least be certain that in 10 years, we’re still going to be ourselves. We’ll likely still be interested in “creating,” so let’s give ourselves what we want!
Anyway, back to reality, and in sharp contrast to the crazy conjecture above, I’m personally comfortable with JavaScript as it is now. I know and appreciate the quirks, and its “shortcomings” that everyone will tell you it has, don’t necessarily feel that way to me. It’s what it is. Tracking the progress of ES6, I’m excited for when it’s finalized and widely available.
In the end, it’s the internet. The book’s not written yet. Wherever we go, we’re taking ourselves there.
Stephen on October 4th, 2012 at 2:21 pm
Nicholas, why the effort?
Google Closure Compiler provides everything that TypeScript does and way more, for years. It already checks for unreachable code, and optimizes your code near to perfect. It’s also less obtrusive, does everything in comments — annotations.
Armagan Amcalar on October 4th, 2012 at 4:04 pm
Above you state the following:
“TypeScript adds additional features on top of JavaScript that then get converted into ECMAScript 5 compatible code by the TypeScript compiler.”
However, the default target version is ECMAScript 3. The compiler does provides a –target option for explicitly targeting ECMAScript 5 though.
Brian on October 4th, 2012 at 4:48 pm
So that’s how you do function annotations on arguments, I was using ‘void’.
Also on your point of debugging there’s support for Source Maps built in as well so helpful when dealing with the more exotic features, like classes.
Aaron Powell on October 4th, 2012 at 5:34 pm
I welcome any change to make web development easier. Not everyone has time to wait for the theoretical improvements in ES6, we have code to write today and JS is killing our productivity. And the fact that classes and types may not event make it into Es6? If it doesn’t, then the argument to stick with standards will be gone. We cannot wait for ES7 for these much needed development productivity helpers.
TypeScript, Dart, GWT, Closure, etc, were all created because teams were unable to build complex applications with the current toolset and language. This isn’t for fun and for forking JS or the community, it is to help the human mind manage complexity and let our tools help us.
tommy on October 4th, 2012 at 7:05 pm
The approach here is exactly that used by Stroustrup to add objects to C. C++ has been quite successful, to say the least.
That is NOT a prediction re TypeScript. My crystal ball is currently in the shop for repairs.
Martin Rinehart on October 5th, 2012 at 6:03 am
This is the best write up I’ve read so far. Good job.
I’m very excited about TypeScript – especially the ability to cleanly define classes and interfaces.
Bart on October 5th, 2012 at 11:58 am
I find it funny that the Typescript team is targeting a version of ECMAScript that is still subject to change while at the same time, the IE team won’t commit to certain features (JS, CSS) because the specs aren’t finished.
Typescript looks interesting though, but like some people pointed out, the Closure compiler already helps relieve some if the same issues.
Mikael Gramont on October 5th, 2012 at 2:41 pm
“…but I also want the web as a whole to continue to grow and get better, and that only happens when we have more competent developers entering the workforce. I see compile-to-JavaScript languages as a barrier to that goal. We should be convincing more people to learn JavaScript rather than giving them more options to not write JavaScript. I often wonder what would happen if all of the teams and companies who spent time, energy, personnel, and money to develop these alternatives instead used those resources on improving JavaScript and teaching it.”
I beg to differ.
I started my career programming machine language and assembly for 6502 processors. The wizardly power that came from controlling every byte that passed through the CPU, always knowing what every register contained, knowing the entire memory map of the computer and how to access it in the most efficient way was a true rush and made me feel invincible as a programmer.
However the scope of what I could do was limited by how close to the metal I was flying. Huge undertakings were not easy. Moving on to high level languages allowed forced me to give up some of that control, but in trade I was able to attempt larger, more complicated programs and finish them quicker.
Compile-to-JavaScript languages are like that. They let you apply useful abstractions like classes, interfaces, inheritance, encapsulation, and OOP design patterns. This allows you to build larger systems in a more maintainable way, that is more team-friendly.
Try to find a decent assembly language programmer who really knows their stuff. You’re going to pay a fortune for them, because its hard and takes a lot of work to achieve mastery. And chances are no mere mortals are going to understand how to maintain their code, so you’ll use it only when needed and use higher level languages like C and C++ for the bulk of your application.
Same goes for JavaScript. The barrier to entry is low – open up notepad and a browser and anyone can do it, so the field is full of people who sling it, but the masters are few and far between. That’s because it’s hard to achieve mastery level JS and in order to do anything significant, you have to be way to damned clever for other people to maintain your code.
Meanwhile in a parallel universe, Object Oriented Programming has design patterns and concepts that a novice can follow and quickly become proficient in developing maintainable code that break a problem into actors with well-defined roles, responsibilities, and collaborations.
Back in the browser, JavaScript Is a bunch of functions and variables in a big global gumbo called window.
TypeScript and Dart allow OOP developers who already have training on how to write maintainable code to apply those skills to the lawless west of the browser.
Cliff Hall on October 5th, 2012 at 4:18 pm
“I see compile-to-JavaScript languages as a barrier to that goal. We should be convincing more people to learn JavaScript rather than giving them more options to not write JavaScript. ”
This. I’ll be the first to agree that JS has its deficiencies, but why can’t we teach developers to write good JS instead of trying to write JS like every other OO language? I’m no BE engineer, but with all the Java I’m writing now, even I know I shouldn’t be creating tons of classless objects and stuffing them into hash maps.
I can’t really say that I’ve ever really thought “gee whiz, if I had type checking and classes in JS, that would really make my life easier.” I’m not sold on the idea that typing or classes or interfaces will somehow “fix” the problems that people seem to have with JS (which are many). I think it would be beneficial to first understand the problems people are trying to address. JS does some rather obtuse things, but often times they stem from either misunderstandings or misuse of the language.
If the solution is to change the language rather than educating the developers, I think that’s a little bit short sighted. Sure, it lowers the barrier of entry in the short term, but it only masks the root of the problem. Until the day JS is either 1) fixed of all of its “bad parts” or 2) become a truly target language, then we will continue to have the problems we have today.
I’ll admit I’m biased, of course, but I feel like I’m missing something in this whole “let’s rewrite JS” movement…
Alex on October 5th, 2012 at 6:13 pm
Nice article! +1
I totally agree with you and that’s why I keep myself as much close as I can to upstream’s vanilla. If you learn -and code- in ECMAScript, you will learn and code ECMAScript, conversely if you learn and code TypeScript, CoffeeScript or PorongaScript you will be learning _that_ dialect and will have your nuts tied to it and, in the case of TypeScript, to a disgusting company like Microsoft is.
Go F/LOSS kids.
Martin C. on October 5th, 2012 at 8:32 pm
One thought that strikes me is this: even if ES-99 conflicts with TypeScript, presumably there’s an upgrade path from ES-98 (ie a browser equipped to run ES-99 will run also run ES-98 source). Thus, you can always take the transpiled output of your TypeScript source (at ES-98 level) and ‘promote’ it to be the ultimate source, and simply ditch TypeScript. So in reality the ‘difficult position’ with respect to classes that Nicholas claims, only applies to the TypeScript development team; it does not apply to users of the language. Make sense?
Dave Gardner on October 5th, 2012 at 8:39 pm
…but can’t we just use jsdoc and good IDE for type checks and autocomplete?..
Alexander on October 6th, 2012 at 3:32 am
In the future, suppose TypeScript 2.0 is out and ECMAScript 7 ships, suppose it has syntax incompatible with TypeScript 2.0. Well then you need a TypeScript 2.0 to TypeScript 3.0 translator, not so difficult code maintenance wise, but you will need to learn the new syntax.
Bill G on October 6th, 2012 at 9:31 am
I agree with Nicholas. I come at JavaScript with an expert knowledge of ActionScript. I find JavaScript to be brutish and clumsy in many ways in comparison but I feel that it makes no sense for me to learn another wrapping language. First off, it’s Microsoft. Ick. Secondly the capabilities of JavaScript will and must change. I’ve no doubt it will one day support formal class structures and typing. The market demands it and it will happen soon. Finally, I believe a good JavaScript developer can currently do adequate troubleshooting and OOP kludging.
Camilo on October 6th, 2012 at 10:03 am
I think JavaScript must step back to ECMAScript 4 and start over from there. Abandoning ECMAScript 4 was a historic failure. I blame all the people involved.
NinjaWarrior1976 on October 7th, 2012 at 9:20 pm
@NinjaWarrior – I disagree. ECMAScript 4 was too large of the language and too big of a change from what we were using. The learning curve was far too steep and it was a good idea to pull back and make iterative changes first.
Nicholas C. Zakas on October 8th, 2012 at 9:15 am
Great article. I believe that TypeScript fulfils a need based on todays version of JavaScript and I see it as only a stop gap until ECMAScript 6 or later version fills in the gaps required for tools to be able to provide the kind of features that other languages enjoy today.
For me, coming from a background of non-JavaScript languages, I find TypeScript to be the bridge I needed to be productive in building JavaScript applications.
Matthew Winter on October 8th, 2012 at 6:54 pm
[...] The talk was great, it was really interesting to hear that Microsoft have been working on this project for 2 years, and to me it shows. If you haven’t tried it out then I encourage you to checkout it’s playground on the official site (start with the Walkthrough: JavaScript then Walkthrough: Types) and read through Nicholas C. Zakas’s very balanced discussion of it’s pros and cons. [...]
Scott Logic » JSConf EU 2012 on October 12th, 2012 at 8:41 am
Comments are automatically closed after 14 days.