useExhaustiveSwitchCases (JavaScript)
Summary
Section titled “Summary”- Rule available since:
v2.0.0 - Diagnostic Category:
lint/nursery/useExhaustiveSwitchCases - This rule has an unsafe fix.
- The default severity of this rule is information.
- This rule belongs to the following domains:
- Sources:
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "useExhaustiveSwitchCases": "error" } } }}Description
Section titled “Description”Require switch-case statements to be exhaustive.
When working with union types in TypeScript, it’s common to want to write a switch statement intended to contain a case for each possible variant. However, if the union type changes, it’s easy to forget to modify the cases to account for any new types.
By default, this rule reports when a switch statement over a value typed as a union of literals lacks
a case for any of those literal types and does not have a default clause.
Set requireExplicitCase to true to check for missing cases even when the switch has a default clause.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”type Day = | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday';
declare const day: Day;let result = 0;
switch (day) { case 'Monday': result = 1; break;}/invalid.ts:13:1 lint/nursery/useExhaustiveSwitchCases FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ The switch statement is not exhaustive.
11 │ let result = 0;
12 │
> 13 │ switch (day) {
│ ^^^^^^^^^^^^^^
> 14 │ case 'Monday':
> 15 │ result = 1;
> 16 │ break;
> 17 │ }
│ ^
18 │
ℹ Some variants of the union type are not handled here.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ These cases are missing:
- "Tuesday"
- "Wednesday"
- "Thursday"
- "Friday"
- "Saturday"
- "Sunday"
ℹ Unsafe fix: Add the missing cases to the switch statement.
14 14 │ case 'Monday':
15 15 │ result = 1;
16 │ - ····break;
16 │ + ····break;
17 │ + ··case·"Tuesday":·throw·new·Error("TODO:·Not·implemented·yet");
18 │ + ··case·"Wednesday":·throw·new·Error("TODO:·Not·implemented·yet");
19 │ + ··case·"Thursday":·throw·new·Error("TODO:·Not·implemented·yet");
20 │ + ··case·"Friday":·throw·new·Error("TODO:·Not·implemented·yet");
21 │ + ··case·"Saturday":·throw·new·Error("TODO:·Not·implemented·yet");
22 │ + ··case·"Sunday":·throw·new·Error("TODO:·Not·implemented·yet");
17 23 │ }
18 24 │
type Day = | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday';
declare const day: Day;let result = 0;
switch (day) { case 'Monday': result = 1; break; case 'Tuesday': result = 2; break; case 'Wednesday': result = 3; break; case 'Thursday': result = 4; break; case 'Friday': result = 5; break; case 'Saturday': result = 6; break; case 'Sunday': result = 7; break;}Options
Section titled “Options”requireExplicitCase
Section titled “requireExplicitCase”Default: false.
A default clause handles any value that does not match a case.
By default, the rule accepts this as covering all remaining values in a union.
This means that adding a value to the union will not produce a diagnostic if the switch has a default clause.
Set requireExplicitCase to true to require a case for each value in the union.
You can still keep default as a fallback for unexpected values at runtime.
{ "linter": { "rules": { "nursery": { "useExhaustiveSwitchCases": { "level": "on", "options": { "requireExplicitCase": true } } } } }}With this option enabled, the switch below passes because "A", "B", and "C" each have a case.
The default clause stays as a runtime fallback. Removing case "C" would produce a diagnostic,
even though the fallback would handle that value.
type Letter = "A" | "B" | "C";declare const letter: Letter;switch (letter) { case "A": case "B": case "C": break; default: throw new Error("Unexpected letter");}Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.