Wednesday, May 13, 2020

Re: JsInterop - fail to iterate @JsType in List


Ok so it does work using an interface! I just cannot declare a static field public static Car car in the interface but introducing a Global class to hold it does the trick!

@JsType(isNative = true)
public class Global {
 @JsProperty(namespace = JsPackage.GLOBAL) public static Car car;

  @JsType(isNative = true)
 public interface Car {
   String start();

And for reference I kept:

   class Car {
     start() {
       return "start";

    var car = new Car();

I really thought I could either use interface or class depending on the best approach to map it to Java.

Anyway to come back to my real code, I was trying to define with JsInterop the Monaco Editor interface: IStandaloneCodeEditor

export interface IStandaloneCodeEditor extends ICodeEditor {
   updateOptions(newOptions: IEditorOptions & IGlobalEditorOptions): void;
   addCommand(keybinding: number, handler: ICommandHandler, context?: string): string | null;
   createContextKey<T>(key: string, defaultValue: T): IContextKey<T>;
   addAction(descriptor: IActionDescriptor): IDisposable;

So I had this JsInterop mapping:

    @JsType(isNative = true)
   public interface IStandaloneCodeEditor extends ICodeEditor {
       String addCommand(@Nonnull KeyCode keyCode, @Nonnull Function handler, @Nullable String context);

But then I wanted to access a private field so I converted my interface to a class and that's where all my troubles came from:

    @JsType(isNative = true)
   public abstract class IStandaloneCodeEditor implements ICodeEditor {
       KeybindingService _standaloneKeybindingService;

        public native String addCommand(@Nonnull KeyCode keyCode, @Nonnull Function handler, @Nullable String context);

So at the end, I have to keep it declared as interface and everything works fine now!

    @JsType(isNative = true)
   public interface IStandaloneCodeEditor extends ICodeEditor {
       @JsProperty(name = "_standaloneKeybindingService")
       KeybindingService _standaloneKeybindingService();

        String addCommand(@Nonnull KeyCode keyCode, @Nonnull Function handler, @Nullable String context);

Thanks for the Babel approach but as you see in this comment, my repro code was not even close to my real issue. My real issue has nothing to do with es2015 class keyword ;)

Thanks all

On Tuesday, May 12, 2020 at 11:36:00 PM UTC+10, Colin Alworth wrote:
Another option could be to tell GWT that this is just the idea of what the Car type will be, but that there isn't actually a real type called Car that it will be able to find. For example, you could perhaps make this an interface instead of a class (js has no actual interface types, just "it quacks, so its a duck"). Another option (but not a good one) is to further modify the `@JsType` to have `name="Object", so that GWT ignores all type checks. This will get weird in j2cl though, as you'll need externs that reflect this code style (though you'll need externs anyway, if monaco isn't capable of being fed to closure-compiler).

I do believe that the es2015 class keyword emits a constructor that GWT can work with though - the limitations for GWT and WebComponents are that you can't "extend" a es2015 class using prototype, and GWT always uses prototype.

If the script block does some scoping (modules perhaps?) that could hide the Car type from GWT, so that it is unable to do the JS `(c instanceof $wnd.Car)` check required to cast the element when it comes out of the generic ArrayList<Car>.get().

You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To view this discussion on the web visit

No comments:

Post a Comment