Skip to content

Remove the non-null assertion operator #9637

Closed
@chrisprice

Description

@chrisprice

Whilst quite hard to search for so I may have missed something, the only justification for the non-null assertion operator I can find is in the design notes #7395 -

Non-null assertion operator

  • A new ! postfix expression-level operator.
  • Produces no runtime-dependent code.
// Compiled with --strictNullChecks
function validateEntity(e: Entity?) {
    // Throw exception if e is null or invalid entity
}
function processEntity(e: Entity?) {
    validateEntity(e);
    let s = e!.name;  // Assert that e is non-null and access name
}
  • Why can't a type predicate take care of that?
  • It could but it's just cumbersome for some scenarios.

So a type predicate would look look like -

function validateEntity(e: Entity?): e is Entity {
    if (e == null) {
        throw new Error();
    }
    return true;
}

 function processEntity(e: Entity?) {
     if (validateEntity(e)) {
         let s = e.name; // Guard asserts e is an Entity (and therefore non-null) and access name
     }
 }

Or implicitly -

 function processEntity(e: Entity?) {
     if (e != null) {
         let s = e.name; // Guard guarantees e is non-null and access name
     }
 }

But am I right in thinking that a type assertion would also work?

 function processEntity(e: Entity?) {
     validateEntity(e);
     let s = (<Entity>e).name; // Assert e is an Entity (and therefore non-null) and access name
 }

If so, this would be my default expectation of how this would work. Adding the new operator means -

  • A new (but fundamentally almost equivalent) operator to learn.
  • When reviewing code, as I would generally treat a type assertion as a code-smell, I now also have to learn to treat ! in the same way.
  • Potential conflict with JavaScript should it ever adopt it as an operator.

Adding this new operator seems like an extreme step to support an edge case with so many existing solutions. However, maybe I'm missing a killer scenarios where this would be useful?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions