angular/packages/compiler-cli/test
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
..
compliance build: improve incremental rebuilds of compliance tests (#55594) 2024-04-30 09:22:46 -07:00
ngtsc fix(compiler-cli): fix type narrowing of @if with aliases (#55835) 2024-05-17 10:15:05 -07:00
BUILD.bazel fix(compiler-cli): identify aliased initializer functions (#54609) 2024-02-26 18:27:15 -08:00
downlevel_decorators_transform_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
extract_i18n_spec.ts refactor(compiler): add handler attribute to XMB output (#54865) 2024-04-29 11:56:32 -07:00
initializer_api_transforms_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
mocks.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
perform_compile_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
perform_watch_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
signal_queries_metadata_transform_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
test_support.ts refactor(core): clean up clang comments and workarounds (#55750) 2024-05-13 11:10:36 -07:00
typescript_support_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00
version_helpers_spec.ts refactor: migrate compiler-cli to prettier formatting (#55485) 2024-04-29 10:25:45 -07:00