From 1a151f2daec7cbb5eb4c990eb3a60b2ebc6135ac Mon Sep 17 00:00:00 2001 From: Matthieu Riegler Date: Tue, 24 Feb 2026 17:54:41 +0100 Subject: [PATCH] docs: add docs for `@switch` Exhaustive type checking (cherry picked from commit 9dc3ca44eceff72898a73378b63b386d338d10a7) --- .../content/guide/templates/control-flow.md | 27 +++++++++++++++++++ tools/manual_api_docs/blocks/switch.md | 27 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/adev/src/content/guide/templates/control-flow.md b/adev/src/content/guide/templates/control-flow.md index a8408cc332e..6d812254739 100644 --- a/adev/src/content/guide/templates/control-flow.md +++ b/adev/src/content/guide/templates/control-flow.md @@ -133,3 +133,30 @@ You can specify multiple conditions for a single block by have consecutive `@cas You can optionally include a `@default` block. The content of the `@default` block displays if none of the preceding case expressions match the switch value. If no `@case` matches the expression and there is no `@default` block, nothing is shown. + +### Exhaustive type checking + +`@switch` supports exhaustive type checking, allowing Angular to verify at compile time that all possible values of a union type are handled. + +By using `@default never;`, you explicitly declare that no remaining cases should exist. If the union type is later extended and a new case is not covered by an @case, Angular’s template type checker will report an error, helping you catch missing branches early. + +```angular-html +@Component({ + template: ` + @switch (state) { + @case ('loggedOut') { + + } + + @case ('loggedIn') { +

Welcome back!

+ } + + @default never; // throws because `@case ('loading')` is missing + } + `, +}) +export class AppComponent { + state: 'loggedOut' | 'loading' | 'loggedIn' = 'loggedOut'; +} +``` diff --git a/tools/manual_api_docs/blocks/switch.md b/tools/manual_api_docs/blocks/switch.md index 500638709a0..ad742361e74 100644 --- a/tools/manual_api_docs/blocks/switch.md +++ b/tools/manual_api_docs/blocks/switch.md @@ -30,3 +30,30 @@ You can specify multiple conditions for a single block by having consecutive `@c **`@switch` does not have fallthrough**, so you do not need an equivalent to a `break` or `return` statement. + +### Exhaustive type checking + +`@switch` supports exhaustive type checking, allowing Angular to verify at compile time that all possible values of a union type are handled. + +By using `@default never;`, you explicitly declare that no remaining cases should exist. If the union type is later extended and a new case is not covered by an @case, Angular’s template type checker will report an error, helping you catch missing branches early. + +```angular-html +@Component({ + template: ` + @switch (state) { + @case ('loggedOut') { + + } + + @case ('loggedIn') { +

Welcome back!

+ } + + @default never; // throws because `@case ('loading')` is missing + } + `, +}) +export class AppComponent { + state: 'loggedOut' | 'loading' | 'loggedIn' = 'loggedOut'; +} +```