Skip to content
Typescript type definition to JsInterop GWT Java types converter
Java TypeScript
Branch: master
Clone or download
Pull request Compare This branch is 3 commits ahead of ltearno:master.

README.asciidoc

Typescript definitions to GWT JsInterop translater

This tools takes Typescript definition files (.d.ts) as input, process them, and then outputs JsInterop Java types for use within a GWT application.

It is written in Typescript and uses the Typescript compiler to parse definition files.

Disclaimer : status of this project

This tool is really in beta stage, many things can be added to render the generated API more user-friendly.

It is ready enough that people interested by it can try and open issues if needed.

It can be useful for people maintaining interop libraries between Javascript and GWT.

Although I don’t have myself GWT projects to work on anymore, it was a long time since I wanted to try this approach of automatically convert typescript files to Java types. The experience has proved to be doable with quite a good success (for example after converting automatically the Angular 4 API to JsInterop, I get 20 or so java errors in the generated API, which requires something like 20 minutes of my time to fix).

If you are interested in contributing this project, either because you like it or because it is useful to you, please feel welcome, I will help you in that sense.

The next commits on this project will surely be code documentation so that you are more welcomed to contribute !

Example of code using the generated classes

This is a working GWT application code using the JsInterop classes generated by this tool from the Typescript description of the DOM api :

...

import static fr.lteconsulting.jsinterop.browser.GlobalScope.*;

public void onModuleLoad() {
    HTMLButtonElement button = (HTMLButtonElement) document.createElement("button");
    button.innerHTML = "<b>Click me</b>";
    button.style.color = "red";
    document.body.appendChild(button);

    button.addEventListener("click", console::log);

    console.log(document);

    setInterval(event -> console.log("a second has gone"), 1000);

    // Promise...
    wait(2500)
        .then(value -> Promise.resolve(42))
        .then(value -> Promise.resolve(value > 10 ? "More than 10" : "Less than 10"))
        .then(value -> {
            console.log(value);
            return null;
        });
}

// And the wait(int duration) method :
private Promise<Void> wait(int duration) {
    return new Promise<>((resolver, rejecter) -> setTimeout(evt -> resolver.call(null), duration));
}

How to use

Compile it with npm install then tsc.

Then launch it with nodejs target/main.js CONFIG_FILE.

Sample configuration files can be found at the root directory (ts2java.browser.config.json for instance).

Example of generated files

The browser environment (the Web API), when using the default lib.es6.d.ts file that is the Typescript description of the Web API for normal Web programming, is generated as in this url : https://github.com/ltearno/typescript2java/tree/master/apis/browser-api/src/main/java/fr/lteconsulting/jsinterop/browser.

The Angular 4 API has also been transcribed to JsInterop with this tool. The result is here : https://github.com/ltearno/angular2-gwt/tree/dev/src/main/java/fr/lteconsulting/jsinterop/ng.

Configuration

Here is a configuration sample :

{
    "sourceRootDir": "./tsd",
    "baseJavaPackage": "fr.lteconsulting.jsinterop",
    "defaultJavaPackage": "browser",
    "javaPackages": {},
    "processInternalTypes": false,
    "outputDirectory": "./out/src/main/java",
    "renaming": {
        "fr.lteconsulting.jsinterop.browser": {
            "IDBValidKey_UnionOfDateAndIDBArrayKeyAndNumberAndString": "IDBValidKey",
            "AVeryLongClassName": "MyPreferredClassName"
        }
    },
    "adding": {
        "fr.lteconsulting.jsinterop.browser": {
            "Array": "added-to-array.txt" (1)
        }
    },
    "removing": {
        "fr.lteconsulting.jsinterop.browser": {
            "Array": [
                "static Array of(T)" (2)
            ]
        }
    }
}
  1. The added-to-array.txt file content will be added to the Array class.

  2. The static of(T value) method will not be generated.

Here is the list of options :

sourceRootDir

Where the .d.ts files are to be found (searched recursively).

baseJavaPackage

Java package that will be affected to generated classes.

defaultJavaPackage

A Java package that will be appended to the baseJavaPackage when no js namespace is found for a js type.

javaPackages

A mapping from the source directories to the corresponding java package (appended to baseJavaPackage).

processInternalTypes

Are ambient js types generated ?

outputDirectory

Base directory for output. Of course, classes files will be put in their correct sub-directories.

renaming

Sometimes the names outputed by the tool are not so handy (especially with many types unions which generate very long names).

This configuration is an associative object organized by package name then by class name.

You can choose the name to which those classes will be renamed.

adding

Sometimes, you want some code to be added in the generated classes.

This is the configuration to use. It is organized by package then name. The specified text is the name of a text file from which the content will be added in the corresponding classes.

removing

Sometimes, you want to remove some methods from classes. This is the configuration to use.

The syntax for specifying methods to remove is not yet documented (but still it is very simple)…​

Architecture

Written in Typescript, executes on NodeJS.

It uses the Typescript compiler to get a type AST from the .d.ts files.

Then those TS types are mapped to a graph of low-level almost-Java-types.

Then micro-transformations are applied on this graph to make the generated Java classes convenient.

The Typescript type system is very rich, in fact far more rich than Java’s one. So there are always different choices for the ts to java mapping policy. This tool tries to take the most user-friendly approach.

Philosophy

The aim is to get a good code automatically, although knowing that some edge cases may be very difficult to handle. During the development of this tool, my objective was to transcript the Angular 4 API and get a result which would be almost OK and not requiring more than 20 minutes of work for polishing. In the end, this objective has been surpassed by large!

Roadmap

There some few things to add :

  • Allow to iterate with the Java for over Arrays, Set, Map and all other Iterables !

  • Linking to already generated APIs like Elemental, …​

  • Many other things…​

Donations

You can donate with bitcoin at this address : 1ATgxg4NDiPR2296B8iTCMx3Gbp7a3JJv7

You can’t perform that action at this time.