-
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
Breaking change to default useDefineForClassFields to true should be clearly documented #45653
Comments
While I understand the sentiment for a mention of this in the release notes, I'm seriously confused about this. You're stating that you want to target ESNext, and this is what you get. The behaviour with define-semantics is in accordance with the ESNext version. ESNext is by definition breaking. If you don't want this, why do you target ESNext? This confuses me to no end. |
I think I'm fine with breaking changes on our My problem was that it took significant digging through the issues and PRs on this repository to even figure out what the breaking change was. I'm not even clear whether it's entirely by design as #45584 was closed for being misleading. I don't know what combination of Finally, |
Makes sense, the tsconfig reference was updated with the new default info already: https://www.typescriptlang.org/tsconfig#useDefineForClassFields But I've also sent a PR adding this to the 4.3 release notes on the website: microsoft/TypeScript-Website#2008 |
It's really not intended to be mutually exclusive. It's just that the decorator support in TypeScript is based on an old (outdated) decorator proposal, and the team is waiting for proper decorator support until the new decorator proposal is finalized. The old decorator proposal is just incompatible with the define-semantics of class fields. This is just what happens with experimental features, and also why the team doesn't add such experimental features anymore. Besides this, class-, method and parameter decorators should continue to work just fine. |
@MartinJohns I get that, but decorators (despite being 'experimental') have been in TS for years and are used by a lot of projects. Meanwhile JS decorators have been in limbo/committee-hell for almost as long and are still only in stage 2. TC39 are aware of this and their own recommendation is the opposite of yours:
I get that initialising fields is now best practice (even though not doing so is not breaking) and TS should emit whatever the compliant JS is for any given ES target, but you're still breaking one feature with another and not documenting it.
They do, but that makes it worse... it's part of the reason why it cost my team (and probably many others) so much time to track down this problem. Property decorators just silently do nothing, but other decorators work (and unit tests that isolate decorators work), it took us a while to identify that it was actually a bug in the JS emitted by TS, and then even longer to track down that it wasn't actually a bug, it was broken on purpose but not documented anywhere. The whole point of using Typescript is to turn run-time errors into compile-time ones, silently applying a secret config change into JS code that hides the actual error is kind of a big fail, as least for how we actually practically use it. Yes, you are technically correct (the best kind of correct) but it still feels like the wrong direction for Typescript.
|
It's tricky in this case, I think, because it's not so much a "secret config change" as just "emitting spec-compliant JS whenever it's possible to do so according to your |
Thanks @orta for updating the docs. Talked to @rbuckton about this, and he points out that some property decorators will work, if you’re just doing some kind of metadata tracking or dependency injection; i.e. if you aren’t trying to replace the property with a getter/setter, so there’s no way we can flat-out disallow property decorators under this combination of settings. We did discuss the possibility of issuing suggestion diagnostics, either in the tsconfig itself (for the suspicious combination of |
Why can't the presence of a decorator change only the decorated field to use assign semantics? That's a non-breaking change and seems a lot better than silently breaking users. |
This seems like it would introduce even more inconsistent and surprising behavior. One of the reasons we introduced Another option we could consider would be to have the default behavior for |
Not for the people who have existing working code that breaks from simply running I don't think how the semantics of current decorators relate to upcoming native decorators matters much, and don't think making decorated fields use set semantics would actually complicate things compared to trying to explain why they suddenly don't work anymore. As someone who's having to explain why things are breaking I think the current situation is complicated and just got a lot more complicated with these new unannounced changes. I would preserve decorators as-is when the
This would be fine too. Our users have |
This issue was about docs, and the release notes have been updated, so I’m going to close. The result from the design meeting (#45718) was that we're open to, but not enthusiastic about, adding a suggestion diagnostic in tsconfig.json. Feel free to continue discussion here, but if someone is passionate about taking further action, I would open a new issue with a proposal. |
Bug Report
In some contexts (I'm not sure exactly which, but
"target": "esnext"
does it)useDefineForClassFields
now defaults totrue
.This is a breaking change for any code with
"experimentalDecorators": true
, but I can't find documentation for it anywhere.🔎 Search Terms
useDefineForClassFields
experimentalDecorators
🕗 Version & Regression Information
The
useDefineForClassFields
flag was introduced in 3.7 but defaulted tofalse
: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifierThis is a known breaking change when using decorators: #35081
In #42663 this was changed so that in some contexts
useDefineForClassFields
now defaults totrue
.There is no mention of
useDefineForClassFields
on https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html (or 4.3, or 4.2, or 4.1)There is a mention on 4.0, but in as different context and the default change isn't mentioned https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#properties-overriding-accessors-and-vice-versa-is-an-error
This is a breaking change for all projects that use decorators, it should be clearly identified as a breaking change.
⏯ Playground Link
This is missing documentation
💻 Code
This is missing documentation
🙁 Actual behavior
Release notes don't mention the breaking change. I'm not even sure which release they should be in.
🙂 Expected behavior
Release notes should clearly document the breaking change.
The text was updated successfully, but these errors were encountered: