question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Suggestion: should non-null assert propagate?

See original GitHub issue

I was wondering whether ! should be taken into account by the dataflow analysis, and I don’t see why it shouldn’t.

It is like a cast that says “this value is not null”, so from this point I guess the compiler could remove undefined/null from future uses.

For example, I use ! to work around #9631, so I have code that looks like (simplified):

protected dataArrayChanged(changes: ChangeRecord[]) {
  // #9631: TS incorrectly infers `change: ChangeRecord | undefined`
  for (const change of changes) {
    for (let i = 0; i < change!.removed.length; i++)
      this.dt.row(i).remove();
    if (change!.addedCount > 0)
      this.dt.rows.add(this.data.slice(change!.index, change!.index + change!.addedCount));
  }
  this.dt.draw();
}

Observe how I added 5 ! to make change not null. The first one could have been enough. After all, once I say “change is not undefined”, there is no reason to assume it could be until I modify the variable again.

// Let's say I know x is not undefined
const x: number | undefined;
// Here x: number | undefined, so x! is required
x!.toString();
// Here x: number because of x! above
x.toString(); // ok

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:4
  • Comments:16 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
buolacommented, Jul 13, 2016

@jods4

Precisely because ! is a cast that removed the undefined/null types, it shouldn’t behave differently than any other cast.

What you’re saying is not necessarily ‘I know it is not undefined’ but more ‘I want to treat it as not undefined in this expression’.

In my opinion, this suggestion would be the same as accepting something like this

function foo(): number | number[] { return 3; }
function frob(x: number): void {}

let some = foo(); //some is of type 'number | number[]'
frob(some as number); //we might know it's a number, so we do this. Okay.
frob(some); //If casts "teach about" types, this would not be an error. Currently, it is.

Another problem would be that, when closures are involved, a variable being ‘not undefined’ in one line doesn’t necessarily mean that it will still be ‘not undefined’ in the next line. However, this is a problem of type assertions in general. For example, the following legal code throws because typescript can’t detect that a is undefined, and it can’t really be expected to.

(function (){
    var a: number | undefined = 3;
    var b = () => { a = undefined; };

    if(a) {
        b();
        console.log(a.toFixed());
    }
})();
1reaction
ChayimFriedman2commented, Apr 13, 2020

@pmoleri TypeScript 3.7 introduced assertion functions exactly for this purpose, and they have clearer syntax and no need for redundant !, while your code suffers from huge in-readability because you use the non-null assertion where the operand can be null, and even expected to.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Suggestion: should non-null assert propagate? · Issue #9640
I was wondering whether ! should be taken into account by the dataflow analysis, and I don't see why it shouldn't.
Read more >
java - How to use @Nullable and @Nonnull annotations more ...
@Nonnull annotation just emphasises that null-verification of the argument is on your side (you have to guarantee that you pass non-null value).
Read more >
Assertion-based Loop Invariant Generation
We will say that a loop L preserves a formula f to express that if f held before an arbitrary iteration of L...
Read more >
Kotlin — combating non-null assertions (!!) | by Igor Wojda
If you are really sure that those variables will not hold null values simply declare them as non-nullable to remove need for safe...
Read more >
Add ability to specify generic type parameters as not-null
If now it would be initial phase of language design, I would suggest to make T means not nullable type and T? to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found