angular/packages/compiler-cli
Alex Rickabaugh 8d93597a82 fix(compiler-cli): fix type narrowing of @if with aliases (#55835)
When an `@if` expression has an alias, only the type of the alias is
currently narrowed. So for example, suppose `value` is `string|undefined`:

```
@if (value; as alias) {
  {{ value.length }} <!-- error, value may be undefined -->
  {{ alias.length }} <!-- no error, alias is narrowed -->
}
```

This is especially noticeable when the expression contains guards which are
preconditions for the aliased expression:

```
@if (a && b; as alias) {...}
```

In this case, `a` would not be narrowed within the body, even though the
`@if` condition forces it to be truthy. This is a bug.

The reason is that aliased expressions were previously type-checked as:

```
var alias = a && b;
if (alias) {
  // nothing other than alias is narrowed
  ...
}
```

One option considered was to emit `const alias` instead of `var alias`.
TypeScript _does_ trace `const` expressions and narrow their individual
components when the overall expression is guarded:

```
const alias = a && b;
if (alias) {
  // a, b are also narrowed
}
```

However, this narrowing has different semantics than if `a && b` appeared
directly in the guard expression. For example, object properties aren't
narrowed with this approach, so component properties (which are referenced
as e.g. `this.a`) would not be narrowed.

Instead, we amend the guard expression to include both the expression _and_ the
alias variable, enforcing that both are narrowed.

```
var alias = a && b;
if ((a && b) && alias) {
  // a, b, and alias all narrowed correctly.
}
```

This form ensures all conditions within the guard expression get narrowed
while also narrowing the alias variable type.

Fixes #52855

PR Close #55835
2024-05-17 10:15:05 -07:00
..
integrationtest refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
linker refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
ngcc refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
private refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
src fix(compiler-cli): fix type narrowing of @if with aliases (#55835) 2024-05-17 10:15:05 -07:00
test fix(compiler-cli): fix type narrowing of @if with aliases (#55835) 2024-05-17 10:15:05 -07:00
BUILD.bazel refactor(compiler-cli): add transform to support signal input in JIT (#53808) 2024-01-10 12:21:05 +00:00
esbuild.config.js refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
index.ts refactor(compiler-cli): support extracting initializer API functions (#54925) 2024-03-26 09:17:20 -07:00
package.json build: update babel dependencies to v7.24.4 (#55257) 2024-04-12 10:21:24 -07:00
tsconfig-build.json refactor(compiler-cli): dismantle View Engine implementation of ngc (#44269) 2021-12-01 10:36:30 -08:00
tsconfig.json build: update tsconfigs to use ES2020 as target and module (#43431) 2021-10-01 18:28:42 +00:00