switch-exhaustiveness-check
switch-case文が網羅的であることを要求します。
TypeScriptで共用体型または列挙型を扱う場合、共用体または列挙型の各型に対して `case` を含めるように設計された `switch` 文を記述することが一般的です。ただし、共用体型または列挙型が変更された場合、新しい型に対応するようにケースを変更することを忘れがちです。
このルールは、リテラルの共用体または列挙型として型指定された値に対する `switch` 文で、これらのリテラル型のいずれかのケースが欠落しており、`default` 句がない場合に報告します。
module.exports = {
"rules": {
"@typescript-eslint/switch-exhaustiveness-check": "error"
}
};
Playgroundでこのルールを試す ↗
オプション
このルールは次のオプションを受け入れます
type Options = [
{
/** If 'true', allow 'default' cases on switch statements with exhaustive cases. */
allowDefaultCaseForExhaustiveSwitch?: boolean;
/** If 'true', require a 'default' clause for switches on non-union types. */
requireDefaultForNonUnion?: boolean;
},
];
const defaultOptions: Options = [
{
allowDefaultCaseForExhaustiveSwitch: true,
requireDefaultForNonUnion: false,
},
];
allowDefaultCaseForExhaustiveSwitch
デフォルトは true です。false に設定すると、このルールは、共用体内のすべてのケースを持ち、*かつ* `default` ケースも含む `switch` 文も報告します。したがって、このオプションを false に設定することで、ルールはより厳格になります。
共用体型に対する `switch` 文が網羅的である場合、最後の `default` ケースはデッドコードの一種になります。さらに、新しい値が共用体型に追加された場合、`default` によって `switch-exhaustiveness-check` ルールが `switch` 文で処理されていない新しいケースを報告できなくなります。
allowDefaultCaseForExhaustiveSwitch
注意点
共用体型で表現されていない型を持つ値が存在する可能性がある場合、網羅的な `switch` 文に冗長な `default` ケースを含めることが便利な場合があります。たとえば、クライアントとサーバー間でバージョンの不一致が発生する可能性のあるアプリケーションでは、新しいソフトウェアバージョンを実行しているサーバーが、クライアントの古い型定義では認識されない値を送信する可能性があります。
プロジェクトに意図的に冗長な `default` ケースがわずかしかない場合は、それぞれに対してインライン ESLint 無効化コメントを使用することをお勧めします。
プロジェクトに意図的に冗長な `default` ケースが多数ある場合は、`allowDefaultCaseForExhaustiveSwitch` を無効にし、`default-case` コア ESLint ルールと、`satisfies never` チェックを使用することをお勧めします。
requireDefaultForNonUnion
デフォルトは false です。true に設定すると、このルールは、共用体型 (たとえば、`number` や `string` など) ではない型を `switch` 文が切り替えており、その `switch` 文に `default` ケースがない場合にも報告します。したがって、このオプションを true に設定することで、ルールはより厳格になります。
これは一般的に、`number` と `string` のスイッチが他のスイッチと同じ網羅性チェックを受けるようにするために望ましいことです。
{ requireDefaultForNonUnion: true }
を使用した場合の、このルールに適合しない追加のコード例
const value: number = Math.floor(Math.random() * 3);
switch (value) {
case 0:
return 0;
case 1:
return 1;
}
Playgroundで開く`value` は共用体型ではないため、`requireDefaultForNonUnion` が有効な場合にのみ、switchケースにデフォルト句が必要です。
例
switchに網羅的なケースがない場合、すべてを埋めるか、デフォルトを追加することで、ルールの指摘を修正します。
リテラルの共用体を操作するコードの例をいくつか示します。
- ❌ 不正
- ✅ 正しい (網羅的)
- ✅ 正しい (デフォルト)
type Day =
| 'Monday'
| 'Tuesday'
| 'Wednesday'
| 'Thursday'
| 'Friday'
| 'Saturday'
| 'Sunday';
declare const day: Day;
let result = 0;
switch (day) {
case 'Monday':
result = 1;
break;
}
Playgroundで開く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;
}
Playgroundで開くtype Day =
| 'Monday'
| 'Tuesday'
| 'Wednesday'
| 'Thursday'
| 'Friday'
| 'Saturday'
| 'Sunday';
declare const day: Day;
let result = 0;
switch (day) {
case 'Monday':
result = 1;
break;
default:
result = 42;
}
Playgroundで開く同様に、列挙型を操作するコードの例をいくつか示します。
- ❌ 不正
- ✅ 正しい (網羅的)
- ✅ 正しい (デフォルト)
enum Fruit {
Apple,
Banana,
Cherry,
}
declare const fruit: Fruit;
switch (fruit) {
case Fruit.Apple:
console.log('an apple');
break;
}
Playgroundで開くenum Fruit {
Apple,
Banana,
Cherry,
}
declare const fruit: Fruit;
switch (fruit) {
case Fruit.Apple:
console.log('an apple');
break;
case Fruit.Banana:
console.log('a banana');
break;
case Fruit.Cherry:
console.log('a cherry');
break;
}
Playgroundで開くenum Fruit {
Apple,
Banana,
Cherry,
}
declare const fruit: Fruit;
switch (fruit) {
case Fruit.Apple:
console.log('an apple');
break;
default:
console.log('a fruit');
break;
}
Playgroundで開く使用しない場合
多数のパーツを持つ共用体型または列挙型を `switch` することがあまりない場合、または意図的に一部のパーツを省略したい場合は、このルールは向いていない可能性があります。
型チェックされたリンターのルールは従来のリンターのルールよりも強力ですが、型チェックされたリンティングを設定する必要もあります。型チェックされたルールを有効にした後にパフォーマンスの低下が発生した場合は、パフォーマンスのトラブルシューティングを参照してください。