ECMAScript 6/7 on the JVM with TypeScript and Vert.x

Following the latest release of Vert.x 3.2, I’ve just uploaded a new version of vertx-lang-typescript 1.1.0. The library adds TypeScript support to Vert.x 3. TypeScript is a programming language that compiles to JavaScript. It supports the ECMAScript 6 (ECMAScript 2015, ES6) specification and also a few parts of ECMAScript 7 (ES7) already.

vertx-lang-typescript automatically compiles Vert.x verticles written in TypeScript to JavaScript and executes them on the JVM. The library also provides type definitions for the Vert.x JavaScript API. Use them in your favourite TypeScript editor/IDE to get auto-completion, API documentation and meaningful error messages (see screencast).

The latest release of vertx-lang-typescript supports TypeScript 1.7. I figured it would be a good idea to give you a couple of examples how this new version helps you use ECMAScript 6 and 7 features on the JVM today.

ECMAScript 6/7 and Vert.x

Below, you find an example verticle written in TypeScript. Well, I left all the TypeScript-specific parts out. In fact the verticle is valid ECMAScript 6 (except for the last snippet [9] which is ECMAScript 7).

First, follow the vertx-lang-typescript README to install the library and to enable TypeScript in Vert.x. Then, extract the type definitions (vertx-lang-typescript-1.1.0-typings.zip) into a new directory. Create a new file named es7verticle.ts in this directory and copy the code below into it. Finally, open your command prompt and execute

$ vertx run es7verticle.ts

This will run a small HTTP server that listens to requests on port 8080. If you open your browser and go to http://localhost:8080, you will see the following:

Output of the verticle written in TypeScript

So far so good. Now let’s have a look at the code. I numbered the individual ECMAScript features used. Here’s a complete list:

  1. Use an arrow function to create a request handler (ES6)
  2. Block-scoped variables do not pollute your global namespace (ES6)
  3. Specify a default value for a function parameter (ES6)
  4. Use rest parameters to collect multiple parameters in an array (ES6)
  5. Spread the contents of an array to function parameters (ES6)
  6. Iterate over array contents using the for…of loop (ES6)
  7. template strings enable string interpolation and multi-line strings (ES6)
  8. Use classes and inheritance (ES6)
  9. Use the new exponentiation operator as a shortcut for Math.pow() (ES7)
/// <reference path="./vertx-js/vertx.d.ts" />
 
// arrow functions *********************************** [1]
vertx.createHttpServer().requestHandler(request => {
  // block-scoped variables (let keyword) ************ [2]
  let response = request.response();
  response.setChunked(true);
 
  // default parameter ******************************* [3]
  function send(msg = "NOOP") {
    response.write(msg);
  }
  send();
  send("\n");
 
  // rest parameters ********************************* [4]
  function sendMulti(...messages) {
    messages.forEach(msg => response.write(msg));
  }
  sendMulti("Hello", " ", "World", "\n");
 
  // spread parameters ******************************* [5]
  let messages = ["Foo", "Bar", "\n"];
  sendMulti(...messages);
 
  // for...of loop *********************************** [6]
  let arr = ["1", "+", "1", "=", "2", "\n"];
  for (let v of arr) {
    send(v);
  }
 
  // multi-line template strings, string interpolation [7]
  let name = "Elvis";
  send(`${name} lives
`);
 
  // classes ***************************************** [8]
  class Animal {
    eat() {
      send("Animal is eating\n");
    }
  }
 
  class Dog extends Animal {
    eat() {
      send("Dog is eating\n");
    }
 
    walk() {
      send("Dog is walking\n");
    }
  }
 
  class Bird extends Animal {
    eat() {
      super.eat();
      send("Animal is a bird\n");
    }
 
    fly() {
      send("Bird is flying\n");
    }
  }
 
  let dog = new Dog();
  let bird = new Bird();
  dog.eat();
  dog.walk();
  bird.eat();
  bird.fly();
 
  // exponentiation operator ************************* [9]
  let i = 5 ** 2;
  send("" + i);
  send("\n");
 
  response.end();
}).listen(8080);

Conclusion

The example demonstrates very well how you can use ECMAScript 6 (and parts of 7) on the JVM today. In fact, there are a lot more cool ES6 features not included in the example such as constants (const), the property shorthand or method properties.

TypeScript is so much more than just ES6. It actually has a very good static type system that allows you to make compile-time type checks. This is makes it much easier to write large Vert.x applications with many verticles. Personally, I really like the support that I get from my IDE when programming TypeScript. Since vertx-lang-typescript comes with type definitions for the Vert.x JavaScript API, I get auto-completion and access to the documentation right in the editor. I mostly use Sublime by the way, but I have tested it successfully with Visual Studio Code, Eclipse and Atom.

Unfortunately, the only ES7 feature that you can use at the moment with vertx-lang-typescript is the exponentiation operator. TypeScript 1.7 also supports decorators but this feature is disabled at the moment in vertx-lang-typescript because it is experimental and subject to change. I’ll keep you up to date when new features are introduced.

Alternatives

Vert.x core developer Paulo Lopes recently published a blog post on how to use ES6 with Vert.x. He uses Babel, a compiler that translates ECMAScript 6 to 5.

Although this approach works well, it is a bit hard to set up and use for my taste. First, you need to wrap your Vert.x application in an NPM package. Second, in order to run your application, you need to compile it with npm run build and then then call npm start.

I haven’t tested this approach but I suppose the fact that you need to wrap your application in a NPM package doesn’t play well with build tools such as Gradle or Maven that you normally would use for a Java project. Additionally, you need to execute two commands to run your verticle. With vertx-lang-typescript you only need one. vertx-lang-typescript also allows you to embed the TypeScript verticle in a larger Vert.x application and mix multiple languages in one project.

Finally, the approach based on Babel only supports ECMAScript 6 (2015), although more features from ES7 will surely be introduced in Babel in the future. TypeScript, on the other hand, gives you much more features such as static typing that you’ll certainly find useful for any larger project.


Profile image of Michel Krämer

Posted by Michel Krämer
on 20 December 2015


Next post

bson4jackson 2.7 has just been released!

I’m happy to announce a new version 2.7 of bson4jackson, the popular library that adds support for binary JSON (BSON) to the Jackson JSON processor. The latest update is a maintenance release.

Previous post

New releases of bson4jackson and gradle-download-task

The two popular libraries just got updates! bson4jackson adds missing hashCode() implementations and supports the MinKey value. gradle-download-task now supports running offline.

Related posts

vertx-lang-typescript 1.0.0

Today, I’m excited to announce the first stable version of vertx-lang-typescript, a library that adds support for TypeScript to Vert.x 3! It allows you to write verticles in TypeScript that are automatically compiled when they are executed.

Build Scala projects with Eclipse Buckminster

Buckminster is a tool to build Eclipse RCP applications. It contains a lightweight Eclipse SDK and features but no means to build Scala projects yet. This post tries to bridge this gap.

10 recipes for gradle-download-task

gradle-download-task is a Gradle plugin that allows you to download files during the build process. This post summarizes common patterns and use cases of gradle-download-task and provides useful tips and tricks.