Description
Before You File a Proposal Please Confirm You Have Done The Following...
- I have searched for related issues and found none that match my proposal.
- I have searched the current rule list and found no rules that match my proposal.
- I have read the FAQ and my problem is not listed.
My proposal is suitable for this project
- I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).
Link to the rule's documentation
https://typescript-eslint.io/rules/switch-exhaustiveness-check/
Description
I like the new default behavior (considerDefaultExhaustiveForUnions: false
), so that I have to explicitly list every union case in a switch statement. However, sometimes there are really big unions where I'd like to rely on the default
case implicitly covering all other cases.
I don't want to disable the switch-exhaustiveness-check
rule with an ESLint comment, because it will likely be missed and kept when changing the default
case, given that it has to be above the switch (…) {
line and not above the default:
line and is thus out of sight.
Example
declare const letter: 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- default case handles letters Q to Z
switch (letter) {
case 'A': {
console.log('A');
break;
}
case 'B': {
console.log('B');
break;
}
case 'C': {
console.log('C');
break;
}
case 'D': {
console.log('D');
break;
}
case 'E': {
console.log('E');
break;
}
case 'F': {
console.log('F');
break;
}
case 'G': {
console.log('G');
break;
}
case 'H': {
console.log('H');
break;
}
case 'I': {
console.log('I');
break;
}
case 'J': {
console.log('J');
break;
}
case 'K': {
console.log('K');
break;
}
case 'L': {
console.log('L');
break;
}
case 'M': {
console.log('M');
break;
}
case 'N': {
console.log('N');
break;
}
case 'O': {
console.log('O');
break;
}
case 'P': {
console.log('P');
break;
}
default: {
console.log('Other');
}
}
Instead, I propose adding a new option value for considerDefaultExhaustiveForUnions
(and maybe even making it the default instead of false
): 'onlyWithComment'
With this option, a default
case on its own would still not be considered exhaustive, but adding a comment right before the default
case would silence the rule.
Example
declare const letter: 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
switch (letter) {
case 'A': {
console.log('A');
break;
}
case 'B': {
console.log('B');
break;
}
case 'C': {
console.log('C');
break;
}
case 'D': {
console.log('D');
break;
}
case 'E': {
console.log('E');
break;
}
case 'F': {
console.log('F');
break;
}
case 'G': {
console.log('G');
break;
}
case 'H': {
console.log('H');
break;
}
case 'I': {
console.log('I');
break;
}
case 'J': {
console.log('J');
break;
}
case 'K': {
console.log('K');
break;
}
case 'L': {
console.log('L');
break;
}
case 'M': {
console.log('M');
break;
}
case 'N': {
console.log('N');
break;
}
case 'O': {
console.log('O');
break;
}
case 'P': {
console.log('P');
break;
}
// default handles letters Q to Z
default: {
console.log('Other');
}
}
Fail
declare const literal: 'a' | 'b';
switch (literal) {
case 'a':
break;
default:
break;
}
Pass
declare const literal: 'a' | 'b';
switch (literal) {
case 'a':
break;
// all other cases
default:
break;
}
Additional Info
No response