closure-compiler icon indicating copy to clipboard operation
closure-compiler copied to clipboard

Cannot compile static properties for classes; static methods are fine

Open ctjlewis opened this issue 5 years ago • 10 comments

class Test {
  static myTest = "abc";
}

fails to compile.

I'm getting around this by doing

class Test {
  static get myTest() { return "abc" };
} 

and @language_out ES5 flag to get some kind of output.

Sadly, static property inheritance seems to really trip up the compiler. Before I relied on static values in my classes, I was able to get it to compile and work on the advanced setting - might even consider reverting my changes just to get it to work 100% again.

Any recommendations also welcome.

ctjlewis avatar Oct 05 '19 11:10 ctjlewis

FYI, static class fields are currently in stage 3 of the TC39 process, so they aren't officially part of the language yet.

https://github.com/tc39/proposal-class-fields

I expect we will start working toward supporting them when they reach stage 4.

brad4d avatar Oct 07 '19 20:10 brad4d

Created Google internal issue http://b/142268971

brad4d avatar Oct 07 '19 20:10 brad4d

@brad4d Any updates on this? Class fields are actually the most effective approach for our library, so it hurts a lot when we can't compile it using this pattern. Consider the root class:

class Widget {
   constructor(...children) { ... }
   build() { ... }
}

Each widget has a tag and an array of classes. To override them without fields, we have to do:

class CustomWidget extends Widget {
    constructor(...children) {
        super(...children);
        this.tag = 'h1';
        this.classes = [ 'class1', 'class2' ];
    }
}

and add this.tag = '', this.classes = [] field sets in the Widget constructor. Not the end of the world, but pretty hideous when it could be:

class Widget {
    // defaults
    tag = 'div';
    classes = ['widget'];

    constructor(...children) {...}
    build() {...}
}

and extend with literally just:

class CustomWidget extends MyWidget {
    tag = 'h2';
    classes = ['custom-widget'];
}

To override the this.tag and this.classes properties on the call to constructor. We want these properties to be ready for when this.build() is called in the future, and this pattern is the most effective way to accomplish this simple use case.

It should really be that simple to transpile fields. Setting a field name = val; inside a class just results in a this.name = val; in the constructor.

Any way I could get some good news on this? I see that the TC39 proposal is still in Stage 3, but Chrome and other browsers support this OOTB and I imagine it would be very easy to implement this for the compiler.

trytelework avatar Jun 07 '20 23:06 trytelework

me too!

vivamexico avatar Feb 04 '21 21:02 vivamexico

See also #2731

xmedeko avatar Dec 21 '21 15:12 xmedeko

+1

DVLP avatar Jun 05 '22 21:06 DVLP

Hi folks, any update on this? We are using static classes/methods/properties to organize our code, it would be great to be able to minify our javascript files.

gsartori avatar Jun 21 '23 06:06 gsartori

We're currently doing work to support both instance and static properties. I'm not sure how long it's going to take to complete. It might be available by 2024Q1

brad4d avatar Jun 26 '23 19:06 brad4d