GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Definite assignment assertions by ahejlsberg · Pull Request #20166 · microsoft/TypeScript

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Nov 20, 2017

Copy link
Copy Markdown
Member

This PR introduces the ability for a variable or property declaration to include a definite assignment assertion in the form of a ! character following the variable or property identifier. A definite assignment assertion instructs the control flow analyzer to always consider the variable definitely assigned, even when the analyzer is unable to prove it.

// Compile with --strict
class C {
    data!: string;  // Suppress strict initialization check
    setData(value: string) {
        this.data = value;
    }
    getData(): string {
        return this.data;
    }
}

In the example above, if it is known that setData will always be called before getData, there is no need to initialize the data property upon construction. However, the control flow analyzer can't make that assumption, and in --strictPropertyInitialization mode (see #20075) it reports an error unless a definite assignment assertion ! is included.

function f() {
    let x!: number;  // Suppress definite assignment check
    doSomethingWithCallback(() => {
        x = 1;
    });
    console.log(x);
}

In the example above, if it is known that doSomethingWithCallback will always invoke the callback before returning, there is no need to initialize x in its declaration. However, the control flow analyzer conservatively assumes that x is used before being assigned in the console.log(x) call and reports an error. A definite assignment assertion can now be included in the declaration to suppress this error.

Definite assignment assertions are permitted only in the following cases:

  • On a property declaration in a class, provided the property has a type annotation and no initializer and isn't static or abstract.
  • On a let or var variable declaration, provided the variable has a type annotation and no initializer.

Related issues: #11463, #12855, #13811.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

piotrwitek, bradleyayers, mgthomas99, ppham27, nisimjoseph, SalathielGenese, listepo-alterpost, faizan-ali-ck, garkin, AllenConway, and 4 more reacted with thumbs up emoji lazdmx and garkin reacted with confused emoji
All reactions
  • 👍 14 reactions
  • 😕 2 reactions
Anders Hejlsberg (ahejlsberg) added 4 commits November 19, 2017 16:48
@ahejlsberg
Definite assignment assertion '!' on variable and property declarations
1624e1b
@ahejlsberg
Accept new baselines
546663a
@ahejlsberg
Allow '!' only on variable declarations within variable statements
2720763
@ahejlsberg
Merge branch 'master' into definiteAssignmentAssertions
ed4dc57
@ahejlsberg
Anders Hejlsberg (ahejlsberg) requested review from Ryan Cavanaugh (RyanCavanaugh) and Mohamed Hegazy (mhegazy) November 20, 2017 19:54
mhegazy
Mohamed Hegazy (mhegazy) reviewed Nov 20, 2017
View reviewed changes

@mhegazy Mohamed Hegazy (mhegazy) left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need some tests for the new token

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ahejlsberg Anders Hejlsberg (ahejlsberg) added this to the TypeScript 2.7 milestone Nov 20, 2017
Anders Hejlsberg (ahejlsberg) added 3 commits November 20, 2017 15:08
@ahejlsberg
Add tests
54d35b9
@ahejlsberg
Accept new baselines
02fd11e
@ahejlsberg
Merge branch 'master' into definiteAssignmentAssertions
9b9f3f2
mhegazy
Mohamed Hegazy (mhegazy) approved these changes Nov 21, 2017
View reviewed changes
@ahejlsberg Anders Hejlsberg (ahejlsberg) mentioned this pull request Nov 21, 2017
Strict property initialization checks in classes #20075
Merged
@ahejlsberg
Anders Hejlsberg (ahejlsberg) merged commit 9abb72d into master Nov 21, 2017
@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the definiteAssignmentAssertions branch November 21, 2017 14:31
@mihailik

mihailik commented Nov 21, 2017

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) what's the best way to add suppression at call site, not globally for the variable?

See your second example, like this:

function f() {
    let x: number;  <---- reluctant to suppress checks for real code   
    doSomethingWithCallback(() => {
        x = 1;
    });
    console.log( x as x! ); <----- prefer to suppress checks at diagnostic call site only 
}
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gcnew

Marin Marinov (gcnew) commented Nov 21, 2017

Copy link
Copy Markdown
Contributor

mihailik I think you are looking for the pre-existing not-null assertion:

console.log( x! )
SlurpTheo and levp reacted with thumbs up emoji mihailik reacted with heart emoji
All reactions
  • 👍 2 reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mihailik

mihailik commented Nov 21, 2017

Copy link
Copy Markdown
Contributor

Marin Marinov (@gcnew) great, but would that work in this case?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gcnew

Marin Marinov (gcnew) commented Nov 21, 2017

Copy link
Copy Markdown
Contributor

mihailik I tested it before posting just to make sure and it worked.

Thinking about it for a second time, is your intention to mark properties as "assigned" in a class constructor under --strictPropertyInitialization? If that's the case, I'm afraid this will not assure the compiler that the property has been assigned. I haven't tried it yet, though.

mihailik reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mihailik

mihailik commented Nov 22, 2017

Copy link
Copy Markdown
Contributor

Marin Marinov (@gcnew) I was referring to the second example in the original post. It's console.log used as one-off diagnostics, where in-place assert is preferable to the wide-scoped change.

Thanks for the syntax!!

gcnew reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ghost ghost mentioned this pull request Dec 6, 2017
Default to single literal type whenever value is omitted #20500
Closed
@cyrilletuzi Cyrille Tuzi (cyrilletuzi) mentioned this pull request Dec 17, 2017
Several issues with strict property checks and definite assignement assertion #20740
Closed
@azz Lucas Azzola (azz) mentioned this pull request Dec 24, 2017
Definite assignment assertions not in AST eslint/typescript-eslint-parser#424
Closed
@ahejlsberg Anders Hejlsberg (ahejlsberg) mentioned this pull request Jan 4, 2018
Weird uninitialized variable error for destructured members of type parameter constrained to homomorphic mapped type where member is declared optional #20994
Closed
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Jan 10, 2018
StrictPropertyInitialization does not understand calls to helpers #21132
Closed
This was referenced Feb 21, 2018
Document strictPropertyInitialization microsoft/TypeScript-Handbook#724
Open
use typeof on return type with T #22030
Closed
@SlurpTheo

SlurpTheo commented Feb 23, 2018

Copy link
Copy Markdown

Any chance this feature could expand a bit to solve ~A2 as well?

image

.ts(616,8): error TS1255: A definite assignment assertion '!' is not permitted in this context.
.ts(621,14): error TS2365: Operator '!==' cannot be applied to types '0' and '1'.
The terminal process terminated with exit code: 1

I know, I know... ~#9998?

Wish: Instead of the TS1255 error when variable declaration has an initial value, TypeScript treats it as a: don't overly-narrow type for later CFA assertion.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tbillington Trent (tbillington) mentioned this pull request Jun 13, 2018
Setters not accounted for by strictNullChecks & strictPropertyInitialization #24937
Closed
@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) Awaiting requested review from RyanCavanaugh
1 more reviewer
@mhegazy Mohamed Hegazy (mhegazy) mhegazy approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

TypeScript 2.7

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@ahejlsberg @mihailik @gcnew @SlurpTheo @mhegazy
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.