Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Merged
ahejlsberg merged 19 commits intomasterfromstrictPropertyInitialization
Nov 20, 2017

Conversation

@ahejlsberg
Copy link
Member

@ahejlsbergahejlsberg commentedNov 16, 2017
edited
Loading

This PR implements a new--strictPropertyInitialization compiler 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 includesundefined or (b) has an explicit initializer or an assignment to the property in the constructor. The--strictPropertyInitialization option has no effect unless--strictNullChecks is also enabled.

The--strictPropertyInitialization switch is part of the--strict family of switches, meaning that it defaults to on in--strict mode. This PR is therefore a breaking change only in--strict mode.

In this example

// Compile with --strictclassTest{a:number;// Error, property not initializedb?:string;// Ok, type includes undefined}

an error is reported on propertya because its type doesn't includeundefined and 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 ofa to includeundefined, by specifying an initial value fora, or by assigning a value toa in the constructor. For example, this is ok:

// Compile with --strictclassTest{a:number=0;// Okb?:string;}

A strict property initialization check is satisfied by assignments in the constructor only when all possible code paths include assignments to the particular property.

// Compile with --strictclassTest{a:number;constructor(startAtZero:boolean){if(startAtZero){this.a=0;}else{this.a=1;}}}

In the example above, an error would occur if either of theif statement branches omitted the assignment tothis.a.

Strict property initialization checks guard against observing uninitialized properties in the constructor body. For example:

// Compile with --strictclassTest{a:number;constructor(){letx=this.a;// Errorthis.a=0;}}

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:

// Compile with --strictclassTest{a:number;constructor(){this.foo();this.a=0;}foo(){// Uninitialized value of 'a' observable here}}

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 usingobj["foo"] syntax).

// Compile with --strictclassTest{a:number;// Error, not initialized"hello world":number;// No check}

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.

// Compile with --strictclassC{a!:number;// Use ! to suppress errorb!:string;// Use ! to suppress errorinitialize(){this.a=0;this.b="hello";}}

Alternatively,// @ts-ignore comments can be used to suppress the errors, or the code can simply be compiled without the--strictPropertyInitialization option.

Fixes#8476.

SlurpTheo, timocov, raveclassic, j-oliveras, helmutschneider, gcnew, nicolashenry, beakbeak, kdama, seikichi, and 71 more reacted with thumbs up emojisampsyo, kdama, sanex3339, eugirdor, mariusschulz, krzkaczor, danizord, listepo-alterpost, and x-strong reacted with laugh emojiraveclassic, j-oliveras, sampsyo, nicolashenry, beakbeak, kdama, KonanMentor, Nipheris, sanex3339, eugirdor, and 10 more reacted with hooray emojiraveclassic, alexrock, sampsyo, nicolashenry, peterkelly, kdama, eugirdor, mariusschulz, itsMapleLeaf, krzkaczor, and 11 more reacted with heart emoji
@RyanCavanaugh
Copy link
Member

Add check forabstract properties

dasois reacted with thumbs up emoji

@itsMapleLeaf
Copy link

Note that strict property initialization checks only guard against observing uninitialized properties after the constructor returns. It is still possible to observe uninitialized properties in methods that are called from the constructor (or from a base constructor).

Is there a reason TS can't check if the called functions access the uninitialized value, then report the error in the constructor?

@weswigham
Copy link
Member

@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.

itsMapleLeaf reacted with thumbs up emoji

@ahejlsbergahejlsberg merged commit148dc4e intomasterNov 20, 2017
@ahejlsbergahejlsberg deleted the strictPropertyInitialization branchNovember 20, 2017 18:44
@abramobagnara
Copy link

abramobagnara commentedNov 21, 2017
edited
Loading

What about initializing helpers?
Suppose that constructor calls a method that complete the initialization (e.g. the developer has put this initialization in a separate method because it should be called also after object construction).
What you propose to handle this case?

mihailik reacted with thumbs up emoji

@ahejlsberg
Copy link
MemberAuthor

@abramobagnara I'd propose one of:

  • Don't use the--strictPropertyInitialization option.
  • Rewrite the code to include initializers or assignments in the constructor.
  • Use definite assignment assertions introduced byDefinite assignment assertions #20166.

@ahejlsberg
Copy link
MemberAuthor

I have edited the PR description to reflect#20166.

@mihailik
Copy link
Contributor

The --strictPropertyInitialization option has no effect unless --strictNullChecks is also enabled.

Will be really useful to have a warning in such case.

@mihailik
Copy link
Contributor

mihailik commentedNov 21, 2017
edited
Loading

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
Copy link
Contributor

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
Copy link
MemberAuthor

Also, does this PR handle cases where error is thrown before all fields initialised?

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).

mihailik and brunocribeiro reacted with thumbs up emoji

@mhegazymhegazy mentioned this pull requestNov 22, 2017
8 tasks
@microsoftmicrosoft locked and limited conversation to collaboratorsJun 14, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@RyanCavanaughRyanCavanaughRyanCavanaugh approved these changes

@DanielRosenwasserDanielRosenwasserAwaiting requested review from DanielRosenwasser

+1 more reviewer

@mhegazymhegazymhegazy approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Check non-undefined properties are initialized in the constructor with--strictNullChecks

8 participants

@ahejlsberg@RyanCavanaugh@itsMapleLeaf@weswigham@abramobagnara@mihailik@mhegazy

[8]ページ先頭

©2009-2025 Movatter.jp