- Notifications
You must be signed in to change notification settings - Fork13.2k
Strict property initialization checks in classes#20075
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
RyanCavanaugh commentedNov 17, 2017
Add check for |
itsMapleLeaf commentedNov 17, 2017
Is there a reason TS can't check if the called functions access the uninitialized value, then report the error in the constructor? |
weswigham commentedNov 17, 2017
@kingdaro we only do control flow analysis across function bounds for immediately invoked function expressions; to do otherwise would be error-prone in the presence of aliasing, so we conservatively avoid doing so. |
abramobagnara commentedNov 21, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
What about initializing helpers? |
ahejlsberg commentedNov 21, 2017
@abramobagnara I'd propose one of:
|
ahejlsberg commentedNov 21, 2017
I have edited the PR description to reflect#20166. |
mihailik commentedNov 21, 2017
Will be really useful to have a warning in such case. |
mihailik commentedNov 21, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Also, does this PR handle cases where error is thrown before all fields initialised? classCar{color:string;constructor(){if(!carsSupportedByBrowser){console.log('Cars not supported');thrownewError('Not supported');}this.color='red';}} |
mihailik commentedNov 21, 2017
And a quirkier variation of previous case: classCar{color:string;constructor(){if(!carsSupportedByBrowser){console.log('Cars not supported ',this);<---seeweexposeinstancewithuninitialisedcolorthrownewError('Not supported');}this.color='red';}} |
ahejlsberg commentedNov 21, 2017
It is fine to throw an exception before all properties are initialized, and yes you can expose an object that isn't fully initialized to the outside (just like you can call methods before the object is fully initialized). |
Uh oh!
There was an error while loading.Please reload this page.
This PR implements a new
--strictPropertyInitializationcompiler option to guard against uninitialized properties in class instances. Strict property initialization checking verifies that each instance property declared in a class either (a) has a type that includesundefinedor (b) has an explicit initializer or an assignment to the property in the constructor. The--strictPropertyInitializationoption has no effect unless--strictNullChecksis also enabled.The
--strictPropertyInitializationswitch is part of the--strictfamily of switches, meaning that it defaults to on in--strictmode. This PR is therefore a breaking change only in--strictmode.In this example
an error is reported on property
abecause its type doesn't includeundefinedand the property declaration doesn't specify an initializer or assign a value to the property in the constructor. The error can be fixed by changing the type ofato includeundefined, by specifying an initial value fora, or by assigning a value toain the constructor. For example, this is ok:A strict property initialization check is satisfied by assignments in the constructor only when all possible code paths include assignments to the particular property.
In the example above, an error would occur if either of the
ifstatement branches omitted the assignment tothis.a.Strict property initialization checks guard against observing uninitialized properties in the constructor body. For example:
Strict property initialization checks also guard against observing uninitialized propertiesafter the constructor returns. However, it is possible to observe uninitialized properties in methods that are called from the constructor (or from a base constructor). For example:
Strict property initialization checks only apply to properties that are declared with proper identifiers. It does not apply to properties with computed names or properties with names specified as string or numeric literals (this is analogous to how control flow analysis isn't applied to properties accessed using
obj["foo"]syntax).In cases where the properties of a class instance are initialized by external means (such as dependency injection) or where it is known that an initialization method is always called before other methods, strict property initialization checks can be suppressed by includingdefinite assignment assertions (#20166) in the declarations of the properties.
Alternatively,
// @ts-ignorecomments can be used to suppress the errors, or the code can simply be compiled without the--strictPropertyInitializationoption.Fixes#8476.