From 3d9ca2f1730689232f0ba1d6eddbd7dcedd1da39 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Tue, 2 Jun 2026 12:11:49 +0200 Subject: [PATCH] fix(compiler-cli): bind switch exhaustive check expressions Ensure switch exhaustive check parameters are visited during template binding so local template symbols are resolved correctly. This allows: ```html @let state = this.state(); @switch (state.mode) { @case ('show') { {{ state.menu }}; } @case ('hide') {} @default never(state); } ``` (cherry picked from commit e8430032e131bbcbede2e30c71b891b425f3574a) --- .../ngtsc/typecheck/test/diagnostics_spec.ts | 21 +++++++++++++++++++ packages/compiler/src/combined_visitor.ts | 1 + 2 files changed, 22 insertions(+) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts index de794ea506c..bc7bf7b4f86 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/diagnostics_spec.ts @@ -1487,6 +1487,27 @@ class TestComponent { expect(messages).toEqual([]); }); + + it('should narrow a let declaration with the same name as a component property', () => { + const messages = diagnose( + ` + @let state = this.state(); + @switch (state.mode) { + @case ('show') { {{ state.menu }}; } + @case ('hide') {} + @default never(state); + } + `, + ` + import {InputSignal} from '@angular/core'; + export class TestComponent { + state: InputSignal<{ mode: 'hide' } | { mode: 'show'; menu: number }>; + } + `, + ); + + expect(messages).toEqual([]); + }); }); // https://github.com/angular/angular/issues/43970 diff --git a/packages/compiler/src/combined_visitor.ts b/packages/compiler/src/combined_visitor.ts index e18876634e4..942dcba373c 100644 --- a/packages/compiler/src/combined_visitor.ts +++ b/packages/compiler/src/combined_visitor.ts @@ -90,6 +90,7 @@ export class CombinedRecursiveAstVisitor extends RecursiveAstVisitor implements visitSwitchBlock(block: t.SwitchBlock): void { this.visit(block.expression); this.visitAllTemplateNodes(block.groups); + block.exhaustiveCheck?.visit(this); } visitSwitchBlockCase(block: t.SwitchBlockCase): void {