Skip to content

noUnsafeOptionalChaining (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"correctness": {
"noUnsafeOptionalChaining": "error"
}
}
}
}

Disallow optional chaining where undefined is not a valid result.

When the value before ?. is null or undefined, JavaScript stops evaluating that chain and returns undefined. Calling that result, reading another property from it, or using it where an object is required can then throw a TypeError.

Parentheses end the protection of an optional chain. For example, (object?.property).name still tries to read name when object?.property produces undefined.

1 in obj?.foo;
code-block.js:1:9 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ 1 in obj?.foo;
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ 1 in obj?.foo;
│ ^^^^^^^^^^^^^
2 │

with (obj?.foo);
code-block.cjs:1:10 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ with (obj?.foo);
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ with (obj?.foo);
│ ^^^^^^^^^^^^^^^^
2 │

for (bar of obj?.foo);
code-block.js:1:16 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ for (bar of obj?.foo);
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ for (bar of obj?.foo);
│ ^^^^^^^^^^^^^^^^^^^^^^
2 │

bar instanceof obj?.foo;
code-block.js:1:19 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ bar instanceof obj?.foo;
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ bar instanceof obj?.foo;
│ ^^^^^^^^^^^^^^^^^^^^^^^
2 │

const { bar } = obj?.foo;
code-block.js:1:20 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ const { bar } = obj?.foo;
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ const { bar } = obj?.foo;
│ ^^^^^^^^^^^^^^^^^^
2 │

(obj?.foo)();
code-block.js:1:5 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ (obj?.foo)();
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ (obj?.foo)();
│ ^^
2 │

(baz?.bar).foo;
code-block.js:1:5 lint/correctness/noUnsafeOptionalChaining ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Unsafe usage of optional chaining.

> 1 │ (baz?.bar).foo;
│ ^^
2 │

ℹ If it short-circuits with 'undefined' the evaluation will throw TypeError here:

> 1 │ (baz?.bar).foo;
│ ^^^
2 │

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