Subscribe / Unsubscribe Enewsletters | Login | Register

Pencil Banner

TypeScript: Industrial-strength JavaScript

Jon Udell | Jan. 20, 2015
The TypeScript language is most succinctly described as an optionally typed superset of JavaScript. Since existing JavaScript is valid TypeScript, you can begin using the TypeScript compiler — and TypeScript-aware tools — by simply changing filename extensions from .js to .ts.

When I tried again in late 2014 I found none of those problems. But my experience was also better, I think, because I approached tasks in a more incremental way.

The first time around, I immediately began refactoring my code to take advantage of TypeScript's support for classes. That's one of the features of the forthcoming ECMAScript 6 that TypeScript makes available now. You can express object-oriented idioms in tomorrow's JavaScript syntax and use the compiler to produce the less convenient and less readable idioms that work in the browser today. In retrospect, the top-down approach wasn't the best way to get started.

The second time around I took a bottom-up approach. I started adding type annotations to otherwise unaltered JavaScript code. As I did so, my grasp of the code improved. Even though mine wasn't a large program, JavaScript's implicit conversion among strings, numbers, and dates had made it hard to visualize the types of objects that flowed into and out of functions. Of course, you can document those expectations in comments, but without strong tool support, such documentation drifts away from the reality of the code. 

With TypeScript that documentation lives as part of the code during the development process, and enables an IDE — in my case Visual Studio — to bring the documentation to life. But it's all a convenient illusion. When you compile to JavaScript, the annotations fall away. If you've done no more than add such annotations, the resulting JavaScript will exactly match your original unannotated code. (If you have restructured the code to use classes and modules, you can use the JavaScript source map the compiler emits for TypeScript-source-level debugging in browsers and stand-alone debuggers.)

"Instead of having a switch that turns types on and off," says Anders Hejlsberg, "we have a dial." You can invest incremental effort for incremental reward. As you add annotations, you improve your own ability to reason about the code, and you enable tools to provide more powerful automated support for that reasoning.

There's also a multiplier effect because the TypeScript compiler works hard to infer types where it can. If you tell it that a function returns a string, it will know that a variable holding the result of that function is a string, even if you haven't annotated the variable with the string type. If you later try to assign it a number, the compiler will complain.

Once I'd checked all my primitive types I began writing simple classes to model JavaScript objects made from primitive types. As I added type annotations for these compound objects, Visual Studio made their members available for code completion. Functions that received — or returned — those objects as parameters became self-describing and self-checking. Again this code awareness flowed through the program. In JavaScript you can't know, a priori, whether the return value you're assigning to a variable is of the type you expect. That uncertainty results in much confusion and error. Why tolerate it?


Previous Page  1  2  3  4  Next Page 

Sign up for Computerworld eNewsletters.