メインコンテンツへスキップ

prefer-optional-chain

連結された論理 AND、否定された論理 OR、または空のオブジェクトの代わりに、簡潔なオプショナルチェーン式を使用することを強制します。

🎨

拡張 "plugin:@typescript-eslint/stylistic-type-checked" ESLint 設定 で有効にすると、このルールが有効になります。

🔧

このルールによって報告される一部の問題は、 --fix ESLint コマンドラインオプション.

によって自動的に修正できます。

このルールによって報告される一部の問題は、エディターの 提案.

によって手動で修正できます。

このルールを実行するには、 型情報 が必要です。

?. オプショナルチェーン式は、オブジェクトが null または undefined の場合に undefined を提供します。オプショナルチェーン演算子は、プロパティ値が null または undefined の場合にのみチェーンするため、論理 AND 演算子のチェーン && に依存するよりもはるかに安全です。これは、任意のの値でチェーンします。また、?. オプショナルチェーンを使用する方が、&& 真偽値チェックよりもコードが少なくなることがよくあります。

このルールは、&& 演算子を ?. オプショナルチェーンで安全に置き換えることができるコードを報告します。

.eslintrc.cjs
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 で開く

オプション

このルールは、次のオプションを受け入れます。

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 型のオペランドをチェックします。

declare const thing: any;

thing && thing.toString();
Playground で開く

checkUnknown

このオプションが true の場合、ルールは「loose boolean」オペランドを検査する際に、unknown 型のオペランドをチェックします。

declare const thing: unknown;

thing && thing.toString();
Playground で開く

checkString

このオプションが true の場合、ルールは「loose boolean」オペランドを検査する際に、string 型のオペランドをチェックします。

declare const thing: string;

thing && thing.toString();
Playground で開く

checkNumber

このオプションが true の場合、ルールは「loose boolean」オペランドを検査する際に、number 型のオペランドをチェックします。

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 に変換すると型エラーが発生します。

declare const thing: true;

thing && thing.toString();
Playground で開く

checkBigInt

このオプションが true の場合、ルールは「緩いブール」オペランドを検査する際に、bigint 型として型付けされたオペランドをチェックします。

declare const thing: bigint;

thing && thing.toString();
Playground で開く

requireNullish

このオプションが true の場合、ルールは「緩いブール」オペランドを検査する際に、null および/または undefined で型付けされていないオペランドをスキップします。

declare const thing1: string | null;
thing1 && thing1.toString();
Playground で開く

使用しない方が良い場合

プロジェクトが正確に型付けされていない場合(TypeScriptへの変換中である場合や、制御フロー分析におけるトレードオフの影響を受けやすい場合など)、特に型安全でないコード領域に対してこのルールを有効にすることは難しいかもしれません。このルールを完全に無効にする代わりに、そのような特定の状況に対してESLintのdisableコメントを使用することを検討してください。

参考資料


型チェックされたLintルールは、従来のLintルールよりも強力ですが、型チェックされたLintの設定も必要です。型チェックされたルールを有効にした後にパフォーマンスの低下が発生した場合は、パフォーマンスのトラブルシューティングを参照してください。

リソース