Skip to content

Optional chaining in template should short-circuit #70143

Description

@PowerKiKi

Which @angular/* package(s) are the source of the bug?

compiler

Is this a regression?

No

Description

Optional chaining in template do not follow ECMA spec, because it does not short-circuit as specified. This is an issue with sub-properties. And the possible workarounds both have significant downsides:

  • Adding extra ? to satisfies Angular is a lie, because the reality of data structure guarantee the sub-property exist, introducing confusion for developers reading the code
  • Disabling strictSafeNavigationTypes disable a lot of otherwise useful type checking, since it essentially means everything is any

It was already reported generally in #37619, and more recently/specifically in #37619 (comment). And despite what that issue says, it was not fixed by #67959 (which fixed a different part of the spec).

It can be reproduce on latest Angular, v22.1.3, with:

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

type MyType = {
  foo: {
    bar: boolean;
  };
};

@Component({
  selector: 'app-root',
  template: `
    @if (value?.foo) {
      this condition compile, it's OK
    }

    @if (value?.foo.bar) {
      this condition should compile, but it does not
    }

    @if (value?.foo.bar ?? true) {
      this condition should compile even more, but it still does not
    }
  `,
})
class App {
  protected value: MyType | null = null;

  constructor() {
    if (this.value?.foo) {
      // it's OK
    }

    if (this.value?.foo.bar) {
      // it's OK
    }

    if (this.value?.foo.bar ?? true) {
      // it's OK
    }
  }
}

bootstrapApplication(App);

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-mrrqakip?file=src%2Fmain.ts

Please provide the exception or error you saw

✘ [ERROR] TS2532: Object is possibly 'undefined'. [plugin angular-compiler]

    src/main.ts:17:19:
      17 │     @if(value?.foo.bar){
         ╵                    ~~~


✘ [ERROR] TS2532: Object is possibly 'undefined'. [plugin angular-compiler]

    src/main.ts:21:20:
      21 │     <@if(value?.foo.bar ?? true){
         ╵                     ~~~

Please provide the environment you discovered this bug in (run ng version)

Angular CLI       : 22.1.3
Angular           : 22.1.1
Node.js           : 22.22.3
Package Manager   : npm 10.8.2
Operating System  : linux x64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build            │ 22.1.3            │ ^22.1.3           │
│ @angular/cli              │ 22.1.3            │ ^22.1.3           │
│ @angular/common           │ 22.1.1            │ ^22.1.1           │
│ @angular/compiler         │ 22.1.1            │ ^22.1.1           │
│ @angular/compiler-cli     │ 22.1.1            │ ^22.1.1           │
│ @angular/core             │ 22.1.1            │ ^22.1.1           │
│ @angular/forms            │ 22.1.1            │ ^22.1.1           │
│ @angular/platform-browser │ 22.1.1            │ ^22.1.1           │
│ @angular/router           │ 22.1.1            │ ^22.1.1           │
│ rxjs                      │ 7.8.2             │ ^7.8.1            │
│ typescript                │ 6.0.3             │ ^6.0.3            │
└───────────────────────────┴───────────────────┴───────────────────┘

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compilerIssues related to `ngc`, Angular's template compilergemini-triagedLabel noting that an issue has been triaged by gemini

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions