Lint Rules

noUnsafeOptionalChaining (since v12.0.0)

This rule is recommended by Rome.

Disallow the use of optional chaining in contexts where the undefined value is not allowed.

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. Also, parentheses limit the scope of short-circuiting in chains.

Examples

Invalid

1 in obj?.foo;
correctness/noUnsafeOptionalChaining.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);
correctness/noUnsafeOptionalChaining.js: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);
correctness/noUnsafeOptionalChaining.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;
correctness/noUnsafeOptionalChaining.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;
correctness/noUnsafeOptionalChaining.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)();
correctness/noUnsafeOptionalChaining.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;
correctness/noUnsafeOptionalChaining.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 │ 
  

Valid

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