JavaScript Transpilers

New languages that are transpiled (translated and compiled) to JavaScript.

All these languages are different attempts to address limitations that exist in the JavaScript language.



Overview


By now you are well aware that JavaScript was not designed for large scale development and that the language is lacking many features that are common in mature, object-oriented languages. One way to address this lack of features is by using Design Patterns as explained in the different sections in this program.

Another approach is to build a new language with the features that are missing from native JavaScript. The only way to run this code in the browser is to translate and compile (transpile) the code into standard JavaScript that is supported by today's browsers. And this is exactly what they do.

Examples of these source-to-source compiled languages include: CoffeeScript, Dart, ClosureScript, and TypeScript. We will briefly touch on each one of these, but mostly TypeScript because it very nicely shows how Design Patterns are used to generate the missing features in standard JavaScript. Let's look at each language.

CoffeeScript, an open source project by Jeremy Ashkenas, is a language with a very clean syntax that uses indentation rather than JavaScript's brackets, braces and semicolons. Its emphasis is on code brevity and it frequently takes up only half the size of similar JavaScript code. In most cases it is easy to see how CoffeeScript gets translated to JavaScript and vice versa. CoffeeScript is widely used and is particularly popular with Ruby developers.

Dart is an open source web programming language developed by Google. It has a C-like syntax and supports classes, interfaces, abstract classes, inheritance, type annotations, and more. An internal Google memo has stated that Dart's goal is to solve JavaScript's problems that cannot be solved by evolving the JavaScript language. Whether they will succeed remains to be seen of course. Dart prefers to run in its own VM, but like the other languages it also compiles to JavaScript.

ClojureScript is a subset of Clojure which is an open source project by Rich Hickey. It is a Lisp-like language in which code is treated as data. It has many features found in Common Lisp and also includes a sophisticated macro system. The original Clojure compiles to Java byte code, but ClojureScript transpiles to JavaScript that runs on all browsers and mobile devices.

Finally, TypeScript is a language that was designed by Microsoft as an open source project. What is unique about TypeScript it that it is JavaScript itself -- all it adds is some syntactic sugar. This is very different from CoffeeScript, Dart, and ClojureScript because these are unique languages with their own syntax, grammar, etc.

The syntactic sugar of TypeScript includes types, classes, modules, and interfaces, but ultimately these get translated to pure JavaScript which will run on any OS and any platform or browser that runs standard JavaScript. This makes TypeScript particularly interesting because it allows us to easily study the mappings between missing language features (classes, modules, interfaces, etc.) and standard JavaScript we use today.

We will see in the following paragraphs that TypeScript gets translated to JavaScript code that makes extensive use of Design Patterns. All of these patterns should be familiar to you because they have been discussed in prior sections.

The TypeScript team has made it very easy to compare TypeScript against the translated JavaScript. Simply visit their website at www.typescriptlang.org and select the play menu item. This will open a playground page where the TypeScript and the resulting JavaScript is displayed side-by-side. Here is a screenshot:

This screen offers instant gratification: you enter TypeScript on the left as you enter the code it gets immediately translated into JavaScript on the right. At the very bottom of the page it states that the playground runs entirely in the browser and no server calls are made. So the TypeScript compiler runs real-time on the client, which is rather impressive.

The dropdown above the TypeScript text box has some walkthrough examples of different features that you can select and study. The image above shows classes; other examples available are for types, modules, inheritance, and a ray tracer example that includes statics, constructors, exports, interfaces, and more.

Next we will examine several TypeScript-to-JavaScript translations. These include the following features and concepts: typing, class, constructor, inheritance, module, interface, export, private, and public.

Typing
Type annotations are an important part of TypeScript. They allow the compiler to enforce the intended contract between the code and a function or variable. Here is an example:

The parameter in the function hello has a type annotation of string. This informs TypeScript that only strings are allowed into hello function calls. However, the argument named person is an array and the compiler detects the problem. The error message states that the "Supplied parameter does not match the signature of the target", which is indeed the case.

Notice that the JavaScript on the right does not have any trace of the type. Typing is only used by the TypeScript editor and compiler to ensure that correct types are used at code and compile time, but the JavaScript output files themselves are not affected. Again, typing is a key aspect of TypeScript and is very helpful in building a robust IDE (integrated development environment), but for our purposes we will not focus on this too much.

class
TypeScript supports classes although JavaScript is a class-less language. We will start off with an empty class.

The class gets mapped to an immediate function in JavaScript. It actually uses the Revealing Module pattern because the nested function named Person is returned. TypeScript considers this nested function the default constructor that has no parameters.

Next we'll add a typed property called name, a constructor that accepts a name, and a method named hello:

The typed string disappears and does not get translated. TypeScript uses it to verify that the name property and the incoming name argument in the constructor are of the same type.

The constructor maps to a private function in JavaScript with the same name. It accepts a name argument which is then assigned to a name property. The hello method is added to Person's prototype allowing all person instances to share this method. The person instance is returned. Notice that the Person prototype method is assigned inside the Person immediate function which actually is a nice way to encapsulate the Person's code. The generated code appears to be robust and highly effective.

interface
Interfaces are another feature supported by TypeScript. We'll look at these next:

The interface ICustomer has two members: a property of type string and a method which takes no arguments and returns a string. The Customer class implements this interface. TypeScript ensures that the interface members, name and getName, are indeed implemented in the class. If not, it shows a red underline under the word class.

Just like type annotations, interfaces are not translated to JavaScript; they are merely used to verify complete and valid implementations of derived classes.

module
Next are modules, which are interesting:

We have a module named MyApp that exports a Customer class. The class itself is the same as the one we saw before. At the bottom we create an instance of Customer, but prefixed with the module name.

On the right we have a global variable MyApp which is passed into the immediate function that creates the Customer. Inside we have the Customer immediate function which is then assigned to the MyApp function argument, which is the module name. The internals of the Customer immediate function are the same as we have seen before.

Notice the argument into the 'module' immediate function, which is (MyApp || (MyApp = {}). This ensures that MyApp exists and is not overwritten in case it was already defined elsewhere.

We have two nested Module patterns: one for the module and another for the class. The class is the Revealing Module pattern because it reveals (returns) the private constructor function of the same name. The module name MyApp turns into the root name of the namespace, hence we are also seeing the Namespace pattern in action. It is quite interesting to see how all these patterns fall into place.

Inheritance
Finally, we will review inheritance.

In TypeScript we have a Person base class and an Employee class which extends Person. The Person constructor has a name parameter with a public access modifier. What this does is it automatically creates an object property with the same name, like this.name (you can see this on the right). This works because in JavaScript all object properties are public. But, interestingly, if you were to prefix it with private then you would see exactly the same (give it a try). The only difference is that TypeScript will ensure that private members are not externally accessed. Finally, having no access modifier leaves the assignment to the developer, thus, this.name = name; is not automatically created.

Employee extends Person. The TypeScript Employee constructor accepts another public parameter named salary. The base class's constructor is called with super(name). Employee also adds its own method, named show which will display an employee's salary. Let's switch to the right and examine the generated JavaScript.

For inheritance to work, TypeScript provides an __extends function you can see at the top right. This function first checks if it already defined elsewhere; if not it create a new function. __extends is similar to the inherit function we have seen under the Mixin Pattern in the Modern Patterns (note: this function is also available as Object.create in newer browsers). The difference is that this function has a this.constructor = d; statement (by the way d = derived class and b = base class). If you have read the section on prototypes it will be clear that this statement is actually very desirable because it ensures that the constructor property is set correctly in all derived objects.

The generated Person class is like all others we have seen before. The Employee is different because it inhertits from Person. It accepts the base class as a parameter named _super in the immediate function. The Employee immediate function make a call to __extends with two arguments: the derived class and the base class, that is, Employee and Person (called _super). The Employee 'constructor' function also makes a call to _super to set the name argument. After that the salary is assigned to its own property. This line was also auto-generated because salary is prefixed with the public keyword in TypeScript.

This completes our review of TypeScript and how it gets translated to standard JavaScript. What we like about this language is that it so clearly validates the notion that Design Patterns are required to getting JavaScript up to a feature level that is generally only available in mature, object-oriented languages.

Whether you use TypeScript in your own work is left up to you. There are numerous JavaScript developers who love these languages that get transpiled to JavaScript because it allows them to increase productivity and the quality and robustness of the JavaScript code they produce. We suggest you experiment with these and see if there is one that meets your needs.