Disallow uninitialised property overrides - #33423
Disallow uninitialised property overrides#33423Nathan Shively-Sanders (sandersn) wants to merge 18 commits into
Conversation
This causes quite a few test breaks. We'll probably want to revert many of them by switching to the upcoming `declare x: number` syntax.
|
TypeScript Bot (@typescript-bot) test this |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the extended test suite on this PR at ac96739. You can monitor the build here. It should now contribute to this PR's status checks. |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the parallelized community code test suite on this PR at ac96739. You can monitor the build here. It should now contribute to this PR's status checks. |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the parallelized Definitely Typed test suite on this PR at ac96739. You can monitor the build here. It should now contribute to this PR's status checks. |
|
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
|
Is there any way how I can test my code against this? From reading your recent PRs it seems that one of my libraries will be affected by the change. |
Will update after checking out other branch for a minute
|
TypeScript Bot (@typescript-bot) pack this The extended tests look pretty grim, but at least this error will be pretty easy to fix. |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the tarball bundle task on this PR at ac96739. You can monitor the build here. It should now contribute to this PR's status checks. |
|
Hey Nathan Shively-Sanders (@sandersn), I've packed this into an installable tgz. You can install it for testing by referencing it in your and then running |
Need to test properties initialised in constructor
|
TypeScript Bot (@typescript-bot) test this |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the parallelized community code test suite on this PR at 8686242. You can monitor the build here. It should now contribute to this PR's status checks. |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the parallelized Definitely Typed test suite on this PR at 8686242. You can monitor the build here. It should now contribute to this PR's status checks. |
|
Heya Nathan Shively-Sanders (@sandersn), I've started to run the extended test suite on this PR at 8686242. You can monitor the build here. It should now contribute to this PR's status checks. |
|
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
|
Rado Kirov (@rkirov) Martin Probst (@mprobst) Evan Martin (@evmar) You will probably want to take a look at this PR too. The errors are easier to fix compared to #33401. |
|
The codefix is in -- Ron Buckton (@rbuckton) I think this is ready for review now. |
And simplify redundant parts of check.
| } | ||
| const constructor = findConstructorDeclaration(node); | ||
| for (const member of node.members) { | ||
| if (getModifierFlags(member) & ModifierFlags.Ambient) { |
There was a problem hiding this comment.
do not require ! on declare x: number (since it is in fact not even allowed)
|
It seems useful to ship |
|
Jordan Harband (@ljharb) Our current plan is to ship the new syntax, the new errors, and the flag to switch to Define semantics at the same time. The flag will initially default to Set semantics, which also silences the errors. People can switch the flag on, fix errors, then switch it off again. Notably, the fixes for both errors are the same with both Set and Define semantics. We'll discuss this at our design meeting on Friday so we should have a final decision then. |
|
Mainly thinking that the declare syntax is at least explicit, and that you may want to hold off merging the rest until after the next TC39 meeting, in case the topic comes up. (not trying to imply anything will change about the proposal) |
|
The errors in #33401 that disable accessor/property override mismatch are independently useful, although admittedly we haven't got many complaints from people confused by the current Set behaviour. |
|
Note: this-property assignments are still incorrectly erroring in JS. |
|
Jordan Harband (@ljharb) I don't see anything on the October 2019 TC39 agenda about this topic, and the deadline for adding agenda items has passed. Class fields have been stable with Define semantics for the whole time they have been at Stage 3, since 2017, and these semantics have shipped unflagged in Firefox, Chrome, and Node.js, as well as other environments. |
|
The deadline is for stage advancement; there’s no deadline for discussion topics, which is what i was alluding to. |
|
Nathan Shively-Sanders (@sandersn) Surprisingly little errors (only 3) in my codebase. I guess I squashed most of them when I switched testing to Babel+Jest. Back then I switched from redefining the class properties to interface merging, i.e. class BaseClass {
property: number
}
interface SubClass {
property: 1 | 2 | 3
}
class SubClass extends BaseClass {
// ...implementation
}which is the ugly brother of the |
|
This is now included in #33509. Thanks all for testing. AlCalzone we decided that interface merging is too esoteric a fix to recommend for the number of errors this causes. Also it's harder to write a codefix for. Jordan Harband (@ljharb) After our design meeting: #33509 has everything in one PR, and will keep the errors behind a flag while adding the new syntax for everyone to use. |
|
Nathan Shively-Sanders (@sandersn) is |
|
Yes. Well, |
|
👍🏻 |
This PR is part of the migration from [[Set]] semantics to [[Define]] semantics. #27644 tracks the complete migration. This is the third step.
Briefly, uninitialised property declarations that must now use new syntax when the property overrides a property in a base class. The new syntax is only allowed in this case and is an error elsewhere. That's because when Typescript supports [[Define]] semantics, it will start emitting uninitialised property declarations, where previously it did not. This will be a major breaking change:
Previously this emitted
When Typescript supports [[Define]] semantics, it will instead emit
which will give both
BandCand propertypwith the valueundefined. (This is an error today withstrictNullChecks: true.)The new syntax will cause Typescript to emit the original JS output:
This PR adds an error prompting the author to add the new syntax in order to avoid the breaking change. As you can see from the baselines, this error is pretty common. From my first run of our extended test suites, it looks pretty common in real code as well.
Note that the compiler can only check constructors for initialisation when
strictNullChecks: true. I chose to be conservative and always issue the error forstrictNullChecks: false.Other ways to fix the error
"strictNullChecks": true.Notes
!is always erased, so, in the last example,p!: 256 | 1000would still result inp === undefinedfor [[Define]] semantics.declareto any uninitialised property, even if it's not an override. I previously had a check that prevented this, but I think an easy upgrade is valuable (you can almost write a regex for it).To test this PR
{ "devDependencies": { "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/44156/artifacts?artifactName=tgz&fileId=1E6A72F0C6E099FF6B046F9DBFDBA5D1CF45DD963781CEFBCFDBBDE15FD60F7C02&fileName=/typescript-3.7.0-insiders.20190916.tgz" } }Future work
The upcoming flag to change class field emit to [[Define]] semantics should disable this error.