no-unsafe-optional-chaining
不允许在不允许 undefined
值的上下文中使用可选链接
在 配置文件 中使用来自 @eslint/js
的 recommended
配置可以启用此规则
可选链接 (?.
) 表达式可以短路,返回值 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 (Defaultfalse
). If this istrue
, this rule warns arithmetic operations on optional chaining expressions, which possibly result inNaN
.
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 中引入。