no-unsafe-optional-chaining
Disallow optional chaining where undefined throws an error
error by default
user?.profile is undefined when user is missing. If you then destructure that result, spread it into an array or a call, loop over it, call it, or read a property of it, you get the TypeError that ?. was there to prevent.
The same goes for the right side of in and instanceof, and for extends. The rule also finds a chain behind await, &&, or ? :, and on the right of || or ??.
This rule is on by default.
Configure#
On by default as an error. To turn it off:
bunfig.toml
[lint.rules]
"no-unsafe-optional-chaining" = "off" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"no-unsafe-optional-chaining" = ["error", {
disallowArithmeticOperators = false,
}]Examples#
example.js4 problems
const { name } = user?.profileUnsafe usage of optional chaining. If it short-circuits with undefined the evaluation will throw TypeError.;
for (const item of order?.itemsUnsafe usage of optional chaining. If it short-circuits with undefined the evaluation will throw TypeError.) {
ship(item);
}
const all = [...order?.itemsUnsafe usage of optional chaining. If it short-circuits with undefined the evaluation will throw TypeError.];
const data = (await response?.json()Unsafe usage of optional chaining. If it short-circuits with undefined the evaluation will throw TypeError.).data;example.jsNo problems
const { name } = user?.profile ?? {};
for (const item of order?.items ?? []) {
ship(item);
}
const all = [...(order?.items ?? [])];
const data = (await response?.json())?.data;Parentheses end the chain. Without them, everything after ?. is skipped when user is missing:
example.js1 problem
const city = (user?.addressUnsafe usage of optional chaining. If it short-circuits with undefined the evaluation will throw TypeError.).city;example.jsNo problems
const city = user?.address.city;Options#
| Option | Default | What it does |
|---|---|---|
disallowArithmeticOperators | false | Also report an optional chain in arithmetic, such as a?.b + 1, -a?.b, or x += a?.b, where undefined gives NaN. |
example.jswith
{ "disallowArithmeticOperators": true }1 problemconst total = cart?.subtotalUnsafe arithmetic operation on optional chaining. It can result in NaN. + shipping;example.jswith
{ "disallowArithmeticOperators": true }No problemsconst total = (cart?.subtotal ?? 0) + shipping;