-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why are TS get/set definedProperties in a class transpiled as enumerable/writable? #3610
Comments
This might actually be a bug.
That second parameter to PropertyDefinitionEvaluation is enumerable.
This part of the spec is hard to trace and it would be good to have more eyes on this if possible. |
/CC: @bterlson |
Sorry for polluting this discussion, but why isn't the result code just use ES5 getters/setters ? Why use defineProperty? |
@gilamran you want to put the instance getters/setters on the prototype of the constructor function, and the static ones on the function itself. there is no other way to create something that is both a function, and set properties on it. you can do this with object literals, but then they are not functions. |
@mhegazy Got it, thanks! |
Sorry I'm late to this thread... Class methods and getters/setters are created with enumerable false, configurable true, writable true. Seems like an ES6 conformance bug. (The rationale here was in part to align classes with the built-in types, eg. consider that Array.prototype.* are non-enumerable). |
We should change our emit to align with the ES6 semantics. This will be a breaking change (probably a large one, relatively speaking), but is required for ES5/ES6 compat. |
I believe I've run into this issue. Here is a repeatable snippet that works as intended when targeting es6 or using Babel. |
Is anyone doing this work? |
Any updates on this? |
I see this is still an issue in 2018. This is clearly a bug. There is an obvious functional difference in the code generated when targeting es5 and when targeting es6. I'm working with code that depends on properties being non-enumerable, so TypeScript targeting es5 simply produces broken code. I believe relying on properties being non-enumerable is a reasonable thing to do, especially given this is the behaviour of all current es6 browsers. Please consider fixing this. If there is too much impact on existing code then an option to control the output variant would be useful and allow a graceful change-over period. |
* Fix Get/Set being enumerable fixes #3610 * fix tests Co-authored-by: Nathan Shively-Sanders <[email protected]>
This was closed with #32264, but this issue description is ambiguous/misleading, as it makes references to Object.definedProperty defaults and "breaking change" of defaults between ES5 and ES6. I would like to provide clarification for potential future readers. The real problem (as hinted by #3610 (comment) later in the discussion) was that there was already get()/set(val) defined for object literals at ES5 (with enumerable: true, configurable: true) (see For anyone wondering about the semantics of Object.defineProperty, that itself DID NOT change between ES5 and ES6- see https://www.ecma-international.org/wp-content/uploads/ECMA-262_5th_edition_december_2009.pdf (ES 5, section 8.12.9);
I would like to note that as a greenhorn JS/TS programmer, I did not realize that there actually was support for get/set in object literals and that it might have different semantics then get/set in class definitions.
Finally, I'd like to add an (opinionated) highlight of important facts from developers PoV when using JS/TS classes, since I had to think about all this when trying to decipher this thread :
What would be my conclusion for writing classes in JS/TS, taking in account ESNext:
|
I just confirmed in the TS Playground that the following TS:
Produces this JS:
This MDN link confirms that, for
Object.definedProperty
accessors:• enumerable: Defaults to false.
• configurable: Defaults to false.
Clearly the generated code is overriding the default values for these keys.
Plowing through the ES6 spec is not something I do. So I’m not sure that ES6 hasn’t changed the defaults. But I’d be surprised.
Now one of the things I miss in TS/ES6 class definitions is the ability to control these keys. It is also not easy to embellish a class with defined properties later … properties that might have non-default definitions
But that’s not my point or my question … which is, why is TS deviating from the defaults?
I get why I’d want the property to be enumerable most of the time – strange that the spec defaults to false. I don’t understand why I should want it to be configurable (maybe because I don't like something about the property TS generated for me?).
In any case, I don’t get how TS (or ES6) gets away with changing the ES5 defaults.
The text was updated successfully, but these errors were encountered: