Skip to main content

prefer-optional-chain

Enforce using concise optional chain expressions instead of chained logical ands, negated logical ors, or empty objects.

🔧

此规则报告的一些问题可通过 --fix ESLint 命令行选项自动修复

💡

此规则报告的一些问题可以通过编辑器 建议 手动修复。

💭

该规则需要 类型信息 才能运行。


如果对象是 nullundefined,则 ?. 可选链表达式提供 undefined。 由于可选链运算符仅在属性值为 nullundefined 时进行链接,因此它比依赖于逻辑 AND 运算符链接 && 安全得多; 它依赖于任何真值。 使用 ?. 可选链的代码通常也比使用 && 真实性检查的代码少。

英:?. optional chain expressions provide undefined if an object is null or undefined. Because the optional chain operator only chains when the property value is null or undefined, it is much safer than relying upon logical AND operator chaining &&; which chains on any truthy value. It is also often less code to use ?. optional chaining than && truthiness checks.

此规则报告可以安全地用 ?. 可选链接替换 && 运算符的代码。

英:This rule reports on code where an && operator can be safely replaced with ?. optional chaining.

.eslintrc.cjs
module.exports = {
"rules": {
"@typescript-eslint/prefer-optional-chain": "error"
}
};
在线运行试试这个规则 ↗

示例

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;
Open in Playground

选项

在下面描述的上下文中,"松散布尔值" 操作数是隐式将值强制为布尔值的任何操作数。 具体来说,非运算符 (!loose) 的参数或逻辑表达式中的裸值 (loose && looser)。

英:In the context of the descriptions below a "loose boolean" operand is any operand that implicitly coerces the value to a boolean. Specifically the argument of the not operator (!loose) or a bare value in a logical expression (loose && looser).

allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing

当此选项为 true 时,规则将不会针对表达式的返回类型发生更改的情况提供自动修复程序。 例如,对于表达式 !foo || foo.bar,表达式的返回类型为 true | T,但对于等效的可选链 foo?.bar,表达式的返回类型为 undefined | T。 因此,将代码从逻辑表达式更改为可选链表达式已经改变了表达式的类型。

英:When this option is true, the rule will not provide an auto-fixer for cases where the return type of the expression would change. For example for the expression !foo || foo.bar the return type of the expression is true | T, however for the equivalent optional chain foo?.bar the return type of the expression is undefined | T. Thus changing the code from a logical expression to an optional chain expression has altered the type of the expression.

在某些情况下,这种区别可能很重要 - 这就是为什么这些修复程序被认为是不安全的 - 它们可能会破坏构建! 例如在下面的代码中:

英:In some cases this distinction may matter - which is why these fixers are considered unsafe - they may break the build! For example in the following code:

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);
Open in Playground

这种代码风格并不常见 - 这意味着将此选项设置为 true 在大多数代码库中应该是安全的。 然而,由于其不安全性,我们将其默认为 false。 为了方便起见,我们提供了此选项,因为它增加了规则涵盖的自动修复案例。 如果你将选项设置为 true,你和你的团队就有责任确保每个修复都是正确和安全的,并且不会破坏构建。

英:This style of code isn't super common - which means having this option set to true should be safe in most codebases. However we default it to false due to its unsafe nature. We have provided this option for convenience because it increases the autofix cases covered by the rule. If you set option to true the onus is entirely on you and your team to ensure that each fix is correct and safe and that it does not break the build.

当此选项为 false 时,不安全的情况将提供建议修复程序而不是自动修复程序 - 这意味着你可以使用 IDE 工具手动应用修复程序。

英:When this option is false unsafe cases will have suggestion fixers provided instead of auto-fixers - meaning you can manually apply the fix using your IDE tooling.

checkAny

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 any 的操作数。

英:When this option is true the rule will check operands that are typed as any when inspecting "loose boolean" operands.

declare const thing: any;

thing && thing.toString();
Open in Playground

checkUnknown

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 unknown 的操作数。

英:When this option is true the rule will check operands that are typed as unknown when inspecting "loose boolean" operands.

declare const thing: unknown;

thing && thing.toString();
Open in Playground

checkString

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 string 的操作数。

英:When this option is true the rule will check operands that are typed as string when inspecting "loose boolean" operands.

declare const thing: string;

thing && thing.toString();
Open in Playground

checkNumber

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 number 的操作数。

英:When this option is true the rule will check operands that are typed as number when inspecting "loose boolean" operands.

declare const thing: number;

thing && thing.toString();
Open in Playground

checkBoolean

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 boolean 的操作数。

英:When this option is true the rule will check operands that are typed as boolean when inspecting "loose boolean" operands.

declare const thing: boolean;

thing && thing.toString();
Open in Playground

checkBigInt

当此选项为 true 时,规则将在检查 "松散布尔值" 操作数时检查键入为 bigint 的操作数。

英:When this option is true the rule will check operands that are typed as bigint when inspecting "loose boolean" operands.

declare const thing: bigint;

thing && thing.toString();
Open in Playground

requireNullish

当此选项为 true 时,规则在检查 "松散布尔值" 操作数时将跳过未使用 null 和/或 undefined 键入的操作数。

英:When this option is true the rule will skip operands that are not typed with null and/or undefined when inspecting "loose boolean" operands.

declare const thing1: string | null;
thing1 && thing1.toString();
Open in Playground

何时不使用它

如果你的项目类型不准确,例如正在转换为 TypeScript 或容易受到 控制流分析中的权衡 的影响,则对于特别是非类型安全的代码区域可能很难启用此规则。 你可以考虑在这些特定情况下使用 ESLint 禁用注释,而不是完全禁用此规则。

英:If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to trade-offs in control flow analysis, it may be difficult to enable this rule for particularly non-type-safe areas of code. You might consider using ESLint disable comments for those specific situations instead of completely disabling this rule.

进一步阅读

选项

该规则接受以下选项

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,
},
];

资源