google / google/closure-compiler
Unable to export an ES6 getter
- Dominant language
- JavaScript
- Stars
- 7.7k
- Forks
- 1.2k
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 6
Description
The following file works under advanced compilation with the class and the method foo() properly exported (e.g. shadowed):
``` JavaScript
goog.provide("namespace.SomeClass");
/**
* @export
*/
namespace.SomeClass = class {
/**
* @param foo {string}
* @export
*/
constructor(foo) {
/**@private @type {string} */
this._foo = foo;
}
/**
* @returns {string}
* @export
*/
foo() {
return this._foo
}
};
```
However, if the foo method is changed to a ES6 getter as such:
``` JavaScript
goog.provide("namespace.SomeClass");
/**
* @export
*/
namespace.SomeClass = class {
/**
* @param foo {string}
* @export
*/
constructor(foo) {
/**@private @type {string} */
this._foo = foo;
}
/**
* @returns {string}
* @export
*/
get foo() {
return this._foo
}
};
```
The compilation will fail with the following errors:
```
SomeClass.js:6: ERROR - @export only applies to symbols/properties defined in the global scope.
convergence.Other = class {
^
SomeClass.js:21: ERROR - @export only applies to symbols/properties defined in the global scope.
get foo() {
^
2 error(s), 0 warning(s), 94.2% typed
```
I am not sure it is related, but when using the getter syntax, with the output set to ES5, the code that is transpiled for the Class makes use of Object.defineProperties. So the foo method is now generated inside code like this:
``` JavaScript
function k(e){this.b=e}
Object.defineProperties(k.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return this.b}}});
```
Here k is the renamed SomeClass. 'this.b' is the renamed 'this._foo'. Object.defineProperties is creating 'a' on the prototype and setting the getter to return 'b' (_foo). It seems like when the code is transpiled we lose the ability to shadow the property for an export. I would have expected to see something like:
``` Javascript
k.prototype.foo = k.prototype.a;
```
Contributor guide
Assessment
This issue has not been assessed yet.