prefer-optional-chain
連結された論理 AND、否定された論理 OR、または空のオブジェクトの代わりに、簡潔なオプショナルチェーン式を使用することを強制します。
拡張 "plugin:@typescript-eslint/stylistic-type-checked"
を ESLint 設定 で有効にすると、このルールが有効になります。
このルールによって報告される一部の問題は、 --fix
ESLint コマンドラインオプション.
このルールによって報告される一部の問題は、エディターの 提案.
このルールを実行するには、 型情報 が必要です。
?.
オプショナルチェーン式は、オブジェクトが null
または undefined
の場合に undefined
を提供します。オプショナルチェーン演算子は、プロパティ値が null
または undefined
の場合にのみチェーンするため、論理 AND 演算子のチェーン &&
に依存するよりもはるかに安全です。これは、任意の真の値でチェーンします。また、?.
オプショナルチェーンを使用する方が、&&
真偽値チェックよりもコードが少なくなることがよくあります。
このルールは、&&
演算子を ?.
オプショナルチェーンで安全に置き換えることができるコードを報告します。
module.exports = {
"rules": {
"@typescript-eslint/prefer-optional-chain": "error"
}
};
Playground でこのルールを試す ↗
例
- ❌ 不正
- ✅ 正しい
foo && foo.a && foo.a.b && foo.a.b.c;
foo && foo['a'] && foo['a'].b && foo['a'].b.c;
foo && foo.a && foo.a.b && foo.a.b.method && foo.a.b.method();
// With empty objects
(((foo || {}).a || {}).b || {}).c;
(((foo || {})['a'] || {}).b || {}).c;
// With negated `or`s
!foo || !foo.bar;
!foo || !foo[bar];
!foo || !foo.bar || !foo.bar.baz || !foo.bar.baz();
// this rule also supports converting chained strict nullish checks:
foo &&
foo.a != null &&
foo.a.b !== null &&
foo.a.b.c != undefined &&
foo.a.b.c.d !== undefined &&
foo.a.b.c.d.e;
Playground で開くfoo?.a?.b?.c;
foo?.['a']?.b?.c;
foo?.a?.b?.method?.();
foo?.a?.b?.c?.d?.e;
!foo?.bar;
!foo?.[bar];
!foo?.bar?.baz?.();
Playground で開くオプション
このルールは、次のオプションを受け入れます。
type Options = [
{
/** Allow autofixers that will change the return type of the expression. This option is considered unsafe as it may break the build. */
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing?: boolean;
/** Check operands that are typed as `any` when inspecting "loose boolean" operands. */
checkAny?: boolean;
/** Check operands that are typed as `bigint` when inspecting "loose boolean" operands. */
checkBigInt?: boolean;
/** Check operands that are typed as `boolean` when inspecting "loose boolean" operands. */
checkBoolean?: boolean;
/** Check operands that are typed as `number` when inspecting "loose boolean" operands. */
checkNumber?: boolean;
/** Check operands that are typed as `string` when inspecting "loose boolean" operands. */
checkString?: boolean;
/** Check operands that are typed as `unknown` when inspecting "loose boolean" operands. */
checkUnknown?: boolean;
/** Skip operands that are not typed with `null` and/or `undefined` when inspecting "loose boolean" operands. */
requireNullish?: boolean;
},
];
const defaultOptions: Options = [
{
checkAny: true,
checkUnknown: true,
checkString: true,
checkNumber: true,
checkBoolean: true,
checkBigInt: true,
requireNullish: false,
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing: false,
},
];
以下の説明のコンテキストでは、「loose boolean」オペランドとは、値を暗黙的にブール値に強制する任意のオペランドです。具体的には、否定演算子の引数 (!loose
) または論理式内の素の値 (loose && looser
) です。
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing
このオプションが true
の場合、式の戻り値の型が変更される場合に、ルールは自動修正を提供します。たとえば、式 !foo || foo.bar
の戻り値の型は true | T
ですが、同等のオプショナルチェーン foo?.bar
の戻り値の型は undefined | T
です。したがって、論理式からオプショナルチェーン式にコードを変更すると、式の型が変更されます。
場合によっては、この区別が重要になる可能性があります。そのため、これらの修正は安全ではないと考えられています。ビルドを壊す可能性があるからです。たとえば、次のコードでは
declare const foo: { bar: boolean } | null | undefined;
declare function acceptsBoolean(arg: boolean): void;
// ✅ typechecks succesfully as the expression only returns `boolean`
acceptsBoolean(foo != null && foo.bar);
// ❌ typechecks UNSUCCESSFULLY as the expression returns `boolean | undefined`
acceptsBoolean(foo?.bar);
Playground で開くこのスタイルのコードはそれほど一般的ではありません。つまり、このオプションを true
に設定すると、ほとんどのコードベースで安全であるはずです。ただし、安全ではない性質のため、デフォルトでは false
に設定されています。このオプションは、ルールでカバーされる自動修正ケースを増やすために、便宜上提供しました。オプションを true
に設定する場合、各修正が正しく安全であり、ビルドを壊さないことを保証する責任は、あなたとあなたのチームに完全にあります。
このオプションが false
の場合、安全でないケースには自動修正の代わりに提案修正が提供されます。つまり、IDE ツールを使用して修正を手動で適用できます。
checkAny
このオプションが true
の場合、ルールは「loose boolean」オペランドを検査する際に、any
型のオペランドをチェックします。
- ❌
checkAny: true
の場合、不正 - ✅
checkAny: false
の場合、正しい
declare const thing: any;
thing && thing.toString();
Playground で開くdeclare const thing: any;
thing && thing.toString();
Playground で開くcheckUnknown
このオプションが true
の場合、ルールは「loose boolean」オペランドを検査する際に、unknown
型のオペランドをチェックします。
- ❌
checkUnknown: true
の場合、不正 - ✅
checkUnknown: false
の場合、正しい
declare const thing: unknown;
thing && thing.toString();
Playground で開くdeclare const thing: unknown;
thing && thing.toString();
Playground で開くcheckString
このオプションが true
の場合、ルールは「loose boolean」オペランドを検査する際に、string
型のオペランドをチェックします。
- ❌
checkString: true
の場合、不正 - ✅
checkString: false
の場合、正しい
declare const thing: string;
thing && thing.toString();
Playground で開くdeclare const thing: string;
thing && thing.toString();
Playground で開くcheckNumber
このオプションが true
の場合、ルールは「loose boolean」オペランドを検査する際に、number
型のオペランドをチェックします。
- ❌
checkNumber: true
の場合、不正 - ✅
checkNumber: false
の場合、正しい
declare const thing: number;
thing && thing.toString();
Playground で開くdeclare const thing: number;
thing && thing.toString();
Playground で開くcheckBoolean
このオプションが true
の場合、ルールは「loose boolean」オペランドを検査する際に、boolean
型のオペランドをチェックします。
このルールは意図的に以下のケースを無視します。
declare const x: false | { a: string };
x && x.a;
!x || x.a;
ブール式は、nullishでない falsy なケースを除外しているため、チェーンを x?.a
に変換すると型エラーが発生します。
- ❌ `checkBoolean: true` の場合は不正です
- ✅ `checkBoolean: false` の場合は正しいです
declare const thing: true;
thing && thing.toString();
Playground で開くdeclare const thing: true;
thing && thing.toString();
Playground で開くcheckBigInt
このオプションが true
の場合、ルールは「緩いブール」オペランドを検査する際に、bigint
型として型付けされたオペランドをチェックします。
- ❌ `checkBigInt: true` の場合は不正です
- ✅ `checkBigInt: false` の場合は正しいです
declare const thing: bigint;
thing && thing.toString();
Playground で開くdeclare const thing: bigint;
thing && thing.toString();
Playground で開くrequireNullish
このオプションが true
の場合、ルールは「緩いブール」オペランドを検査する際に、null
および/または undefined
で型付けされていないオペランドをスキップします。
- ❌ `requireNullish: true` の場合は不正です
- ✅ `requireNullish: true` の場合は正しいです
declare const thing1: string | null;
thing1 && thing1.toString();
Playground で開くdeclare const thing1: string | null;
thing1?.toString();
declare const thing2: string;
thing2 && thing2.toString();
Playground で開く使用しない方が良い場合
プロジェクトが正確に型付けされていない場合(TypeScriptへの変換中である場合や、制御フロー分析におけるトレードオフの影響を受けやすい場合など)、特に型安全でないコード領域に対してこのルールを有効にすることは難しいかもしれません。このルールを完全に無効にする代わりに、そのような特定の状況に対してESLintのdisableコメントを使用することを検討してください。
参考資料
型チェックされたLintルールは、従来のLintルールよりも強力ですが、型チェックされたLintの設定も必要です。型チェックされたルールを有効にした後にパフォーマンスの低下が発生した場合は、パフォーマンスのトラブルシューティングを参照してください。