useOptionalChain (since v1.0.0)
Diagnostic Category: lint/complexity/useOptionalChain
Source: prefer-optional-chain
Enforce using concise optional chain instead of chained logical expressions.
TypeScript 3.7 added support for the optional chain operator.
This operator allows you to safely access properties and methods on objects when they are potentially null
or undefined
.
The optional chain operator only chains when the property value is null
or undefined
.
It is much safer than relying upon logical operator chaining; which chains on any truthy value.
Examples
Section titled ExamplesInvalid
Section titled Invalidfoo && foo.bar && foo.bar.baz && foo.bar.baz.buzz
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - foo·&&·foo.bar·&&·foo.bar.baz·&&·foo.bar.baz.buzz
1 │ + foo?.bar?.baz?.buzz
2 2 │
foo.bar && foo.bar.baz.buzz
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ foo.bar && foo.bar.baz.buzz
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - foo.bar·&&·foo.bar.baz.buzz
1 │ + foo.bar?.baz.buzz
2 2 │
foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz.buzz
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz.buzz
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - foo·!==·undefined·&&·foo.bar·!=·undefined·&&·foo.bar.baz·!==·null·&&·foo.bar.baz.buzz
1 │ + foo?.bar?.baz?.buzz
2 2 │
((foo || {}).bar || {}).baz;
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ ((foo || {}).bar || {}).baz;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - ((foo·||·{}).bar·||·{}).baz;
1 │ + foo?.bar?.baz;
2 2 │
(await (foo1 || {}).foo2 || {}).foo3;
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ (await (foo1 || {}).foo2 || {}).foo3;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - (await·(foo1·||·{}).foo2·||·{}).foo3;
1 │ + (await·foo1?.foo2)?.foo3;
2 2 │
(((typeof x) as string) || {}).bar;
complexity/useOptionalChain.js:1:1 lint/complexity/useOptionalChain FIXABLE ━━━━━━━━━━━━━━━━━━━━━━
✖ Change to an optional chain.
> 1 │ (((typeof x) as string) || {}).bar;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Unsafe fix: Change to an optional chain.
1 │ - (((typeof·x)·as·string)·||·{}).bar;
1 │ + ((typeof·x)·as·string)?.bar;
2 2 │
Valid
Section titled Validfoo && bar;
foo || {};
(foo = 2 || {}).bar;
foo || foo.bar;
foo["some long"] && foo["some long string"].baz