no-unsafe-optional-chaining

不允许在不允许 undefined 值的上下文中使用可选链接

Recommended

配置文件 中使用来自 @eslint/jsrecommended 配置可以启用此规则

可选链接 (?.) 表达式可以短路,返回值 undefined。因此,将评估的可选链接表达式视为函数、对象、数字等,可能会导致 TypeError 或意外结果。例如:

¥The optional chaining (?.) expression can short-circuit with a return value of undefined. Therefore, treating an evaluated optional chaining expression as a function, object, number, etc., can cause TypeError or unexpected results. For example:

var obj = undefined;

1 in obj?.foo;  // TypeError
with (obj?.foo);  // TypeError
for (bar of obj?.foo);  // TypeError
bar instanceof obj?.foo;  // TypeError
const { bar } = obj?.foo;  // TypeError

此外,括号限制了链中短路的范围。例如:

¥Also, parentheses limit the scope of short-circuiting in chains. For example:

var obj = undefined;

(obj?.foo)(); // TypeError
(obj?.foo).bar; // TypeError

规则详情

¥Rule Details

此规则旨在检测使用可选链接无法防止运行时错误的某些情况。特别是,它在短路到 undefined 导致之后抛出 TypeError 的位置标记可选链接表达式。

¥This rule aims to detect some cases where the use of optional chaining doesn’t prevent runtime errors. In particular, it flags optional chaining expressions in positions where short-circuiting to undefined causes throwing a TypeError afterward.

此规则的错误代码示例:

¥Examples of incorrect code for this rule:

在线运行
/*eslint no-unsafe-optional-chaining: "error"*/

(obj?.foo)();

(obj?.foo).bar;

(foo?.()).bar;

(foo?.()).bar();

(obj?.foo ?? obj?.bar)();

(foo || obj?.foo)();

(obj?.foo && foo)();

(foo ? obj?.foo : bar)();

(foo, obj?.bar).baz;

(obj?.foo)`template`;

new (obj?.foo)();

[...obj?.foo];

bar(...obj?.foo);

1 in obj?.foo;

bar instanceof obj?.foo;

for (bar of obj?.foo);

const { bar } = obj?.foo;

[{ bar } = obj?.foo] = [];

with (obj?.foo);

class A extends obj?.foo {}

var a = class A extends obj?.foo {};

async function foo () {
    const { bar } = await obj?.foo;
   (await obj?.foo)();
   (await obj?.foo).bar;
}

此规则的正确代码示例:

¥Examples of correct code for this rule:

在线运行
/*eslint no-unsafe-optional-chaining: "error"*/

(obj?.foo)?.();

obj?.foo();

(obj?.foo ?? bar)();

obj?.foo.bar;

obj.foo?.bar;

foo?.()?.bar;

(obj?.foo ?? bar)`template`;

new (obj?.foo ?? bar)();

var baz = {...obj?.foo};

const { bar } = obj?.foo || baz;

async function foo () {
  const { bar } = await obj?.foo || baz;
   (await obj?.foo)?.();
   (await obj?.foo)?.bar;
}

选项

¥Options

此规则有一个对象选项:

¥This rule has an object option:

  • disallowArithmeticOperators:禁止对可选链接表达式进行算术运算(默认 false)。如果这是 true,则此规则会警告对可选链接表达式的算术运算,这可能会导致 NaN

    ¥disallowArithmeticOperators: Disallow arithmetic operations on optional chaining expressions (Default false). If this is true, this rule warns arithmetic operations on optional chaining expressions, which possibly result in NaN.

disallowArithmeticOperators

将此选项设置为 true 时,将针对以下情况强制执行规则:

¥With this option set to true the rule is enforced for:

  • 一元运算符:-, +

    ¥Unary operators: -, +

  • 算术运算符:+, -, /, *, %, **

    ¥Arithmetic operators: +, -, /, *, %, **

  • 赋值运算符:+=, -=, /=, *=, %=, **=

    ¥Assignment operators: +=, -=, /=, *=, %=, **=

使用 { "disallowArithmeticOperators": true } 选项的此规则的其他错误代码示例:

¥Examples of additional incorrect code for this rule with the { "disallowArithmeticOperators": true } option:

在线运行
/*eslint no-unsafe-optional-chaining: ["error", { "disallowArithmeticOperators": true }]*/

+obj?.foo;
-obj?.foo;

obj?.foo + bar;
obj?.foo - bar;
obj?.foo / bar;
obj?.foo * bar;
obj?.foo % bar;
obj?.foo ** bar;

baz += obj?.foo;
baz -= obj?.foo;
baz /= obj?.foo;
baz *= obj?.foo;
baz %= obj?.foo;
baz **= obj?.foo;

async function foo () {
  +await obj?.foo;
  await obj?.foo + bar;
  baz += await obj?.foo;
}

版本

此规则是在 ESLint v7.15.0 中引入。

资源

ESLint 中文网
粤ICP备13048890号