@typescript-eslint/eslint-plugin 8.33.1-alpha.5 → 8.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -10
- package/docs/rules/README.md +0 -57
- package/docs/rules/TEMPLATE.md +0 -36
- package/docs/rules/adjacent-overload-signatures.mdx +0 -105
- package/docs/rules/array-type.mdx +0 -126
- package/docs/rules/await-thenable.mdx +0 -184
- package/docs/rules/ban-ts-comment.mdx +0 -165
- package/docs/rules/ban-tslint-comment.mdx +0 -45
- package/docs/rules/ban-types.md +0 -26
- package/docs/rules/block-spacing.md +0 -15
- package/docs/rules/brace-style.md +0 -15
- package/docs/rules/camelcase.md +0 -15
- package/docs/rules/class-literal-property-style.mdx +0 -112
- package/docs/rules/class-methods-use-this.mdx +0 -135
- package/docs/rules/comma-dangle.md +0 -15
- package/docs/rules/comma-spacing.md +0 -15
- package/docs/rules/consistent-generic-constructors.mdx +0 -87
- package/docs/rules/consistent-indexed-object-style.mdx +0 -105
- package/docs/rules/consistent-return.mdx +0 -51
- package/docs/rules/consistent-type-assertions.mdx +0 -196
- package/docs/rules/consistent-type-definitions.mdx +0 -133
- package/docs/rules/consistent-type-exports.mdx +0 -97
- package/docs/rules/consistent-type-imports.mdx +0 -139
- package/docs/rules/default-param-last.mdx +0 -59
- package/docs/rules/dot-notation.mdx +0 -94
- package/docs/rules/explicit-function-return-type.mdx +0 -359
- package/docs/rules/explicit-member-accessibility.mdx +0 -353
- package/docs/rules/explicit-module-boundary-types.mdx +0 -287
- package/docs/rules/func-call-spacing.md +0 -15
- package/docs/rules/indent.md +0 -15
- package/docs/rules/init-declarations.mdx +0 -12
- package/docs/rules/key-spacing.md +0 -15
- package/docs/rules/keyword-spacing.md +0 -15
- package/docs/rules/lines-around-comment.md +0 -15
- package/docs/rules/lines-between-class-members.md +0 -15
- package/docs/rules/max-params.mdx +0 -54
- package/docs/rules/member-delimiter-style.md +0 -15
- package/docs/rules/member-ordering.mdx +0 -1483
- package/docs/rules/method-signature-style.mdx +0 -124
- package/docs/rules/naming-convention.mdx +0 -755
- package/docs/rules/no-array-constructor.mdx +0 -34
- package/docs/rules/no-array-delete.mdx +0 -44
- package/docs/rules/no-base-to-string.mdx +0 -115
- package/docs/rules/no-confusing-non-null-assertion.mdx +0 -75
- package/docs/rules/no-confusing-void-expression.mdx +0 -148
- package/docs/rules/no-deprecated.mdx +0 -119
- package/docs/rules/no-dupe-class-members.mdx +0 -16
- package/docs/rules/no-duplicate-enum-values.mdx +0 -66
- package/docs/rules/no-duplicate-imports.mdx +0 -17
- package/docs/rules/no-duplicate-type-constituents.mdx +0 -89
- package/docs/rules/no-dynamic-delete.mdx +0 -64
- package/docs/rules/no-empty-function.mdx +0 -94
- package/docs/rules/no-empty-interface.mdx +0 -75
- package/docs/rules/no-empty-object-type.mdx +0 -150
- package/docs/rules/no-explicit-any.mdx +0 -177
- package/docs/rules/no-extra-non-null-assertion.mdx +0 -60
- package/docs/rules/no-extra-parens.md +0 -15
- package/docs/rules/no-extra-semi.md +0 -15
- package/docs/rules/no-extraneous-class.mdx +0 -329
- package/docs/rules/no-floating-promises.mdx +0 -282
- package/docs/rules/no-for-in-array.mdx +0 -67
- package/docs/rules/no-implied-eval.mdx +0 -106
- package/docs/rules/no-import-type-side-effects.mdx +0 -80
- package/docs/rules/no-inferrable-types.mdx +0 -113
- package/docs/rules/no-invalid-this.mdx +0 -16
- package/docs/rules/no-invalid-void-type.mdx +0 -119
- package/docs/rules/no-loop-func.mdx +0 -12
- package/docs/rules/no-loss-of-precision.mdx +0 -17
- package/docs/rules/no-magic-numbers.mdx +0 -131
- package/docs/rules/no-meaningless-void-operator.mdx +0 -61
- package/docs/rules/no-misused-new.mdx +0 -53
- package/docs/rules/no-misused-promises.mdx +0 -314
- package/docs/rules/no-misused-spread.mdx +0 -132
- package/docs/rules/no-mixed-enums.mdx +0 -96
- package/docs/rules/no-namespace.mdx +0 -157
- package/docs/rules/no-non-null-asserted-nullish-coalescing.mdx +0 -60
- package/docs/rules/no-non-null-asserted-optional-chain.mdx +0 -46
- package/docs/rules/no-non-null-assertion.mdx +0 -48
- package/docs/rules/no-parameter-properties.mdx +0 -16
- package/docs/rules/no-redeclare.mdx +0 -79
- package/docs/rules/no-redundant-type-constituents.mdx +0 -102
- package/docs/rules/no-require-imports.mdx +0 -114
- package/docs/rules/no-restricted-imports.mdx +0 -84
- package/docs/rules/no-restricted-types.mdx +0 -70
- package/docs/rules/no-shadow.mdx +0 -143
- package/docs/rules/no-this-alias.mdx +0 -124
- package/docs/rules/no-type-alias.mdx +0 -626
- package/docs/rules/no-unnecessary-boolean-literal-compare.mdx +0 -165
- package/docs/rules/no-unnecessary-condition.mdx +0 -293
- package/docs/rules/no-unnecessary-parameter-property-assignment.mdx +0 -42
- package/docs/rules/no-unnecessary-qualifier.mdx +0 -57
- package/docs/rules/no-unnecessary-template-expression.mdx +0 -108
- package/docs/rules/no-unnecessary-type-arguments.mdx +0 -85
- package/docs/rules/no-unnecessary-type-assertion.mdx +0 -97
- package/docs/rules/no-unnecessary-type-constraint.mdx +0 -61
- package/docs/rules/no-unnecessary-type-conversion.mdx +0 -79
- package/docs/rules/no-unnecessary-type-parameters.mdx +0 -255
- package/docs/rules/no-unsafe-argument.mdx +0 -98
- package/docs/rules/no-unsafe-assignment.mdx +0 -101
- package/docs/rules/no-unsafe-call.mdx +0 -120
- package/docs/rules/no-unsafe-declaration-merging.mdx +0 -65
- package/docs/rules/no-unsafe-enum-comparison.mdx +0 -98
- package/docs/rules/no-unsafe-function-type.mdx +0 -65
- package/docs/rules/no-unsafe-member-access.mdx +0 -81
- package/docs/rules/no-unsafe-return.mdx +0 -126
- package/docs/rules/no-unsafe-type-assertion.mdx +0 -63
- package/docs/rules/no-unsafe-unary-minus.mdx +0 -60
- package/docs/rules/no-unused-expressions.mdx +0 -52
- package/docs/rules/no-unused-vars.mdx +0 -136
- package/docs/rules/no-use-before-define.mdx +0 -98
- package/docs/rules/no-useless-constructor.mdx +0 -21
- package/docs/rules/no-useless-empty-export.mdx +0 -53
- package/docs/rules/no-useless-template-literals.mdx +0 -9
- package/docs/rules/no-var-requires.mdx +0 -77
- package/docs/rules/no-wrapper-object-types.mdx +0 -75
- package/docs/rules/non-nullable-type-assertion-style.mdx +0 -47
- package/docs/rules/object-curly-spacing.md +0 -15
- package/docs/rules/only-throw-error.mdx +0 -150
- package/docs/rules/padding-line-between-statements.md +0 -15
- package/docs/rules/parameter-properties.mdx +0 -522
- package/docs/rules/prefer-as-const.mdx +0 -51
- package/docs/rules/prefer-destructuring.mdx +0 -101
- package/docs/rules/prefer-enum-initializers.mdx +0 -68
- package/docs/rules/prefer-find.mdx +0 -45
- package/docs/rules/prefer-for-of.mdx +0 -50
- package/docs/rules/prefer-function-type.mdx +0 -98
- package/docs/rules/prefer-includes.mdx +0 -81
- package/docs/rules/prefer-literal-enum-member.mdx +0 -111
- package/docs/rules/prefer-namespace-keyword.mdx +0 -51
- package/docs/rules/prefer-nullish-coalescing.mdx +0 -349
- package/docs/rules/prefer-optional-chain.mdx +0 -304
- package/docs/rules/prefer-promise-reject-errors.mdx +0 -78
- package/docs/rules/prefer-readonly-parameter-types.mdx +0 -408
- package/docs/rules/prefer-readonly.mdx +0 -111
- package/docs/rules/prefer-reduce-type-parameter.mdx +0 -66
- package/docs/rules/prefer-regexp-exec.mdx +0 -52
- package/docs/rules/prefer-return-this-type.mdx +0 -93
- package/docs/rules/prefer-string-starts-ends-with.mdx +0 -84
- package/docs/rules/prefer-ts-expect-error.mdx +0 -86
- package/docs/rules/promise-function-async.mdx +0 -143
- package/docs/rules/quotes.md +0 -15
- package/docs/rules/related-getter-setter-pairs.mdx +0 -61
- package/docs/rules/require-array-sort-compare.mdx +0 -89
- package/docs/rules/require-await.mdx +0 -53
- package/docs/rules/restrict-plus-operands.mdx +0 -245
- package/docs/rules/restrict-template-expressions.mdx +0 -167
- package/docs/rules/return-await.mdx +0 -339
- package/docs/rules/semi.md +0 -15
- package/docs/rules/sort-type-constituents.mdx +0 -209
- package/docs/rules/sort-type-union-intersection-members.mdx +0 -16
- package/docs/rules/space-before-blocks.md +0 -15
- package/docs/rules/space-before-function-paren.md +0 -15
- package/docs/rules/space-infix-ops.md +0 -15
- package/docs/rules/strict-boolean-expressions.mdx +0 -184
- package/docs/rules/switch-exhaustiveness-check.mdx +0 -280
- package/docs/rules/triple-slash-reference.mdx +0 -129
- package/docs/rules/type-annotation-spacing.md +0 -15
- package/docs/rules/typedef.mdx +0 -350
- package/docs/rules/unbound-method.mdx +0 -114
- package/docs/rules/unified-signatures.mdx +0 -132
- package/docs/rules/use-unknown-in-catch-callback-variable.mdx +0 -97
@@ -1,349 +0,0 @@
|
|
1
|
-
---
|
2
|
-
description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining.'
|
3
|
-
---
|
4
|
-
|
5
|
-
import Tabs from '@theme/Tabs';
|
6
|
-
import TabItem from '@theme/TabItem';
|
7
|
-
|
8
|
-
> 🛑 This file is source code, not the primary documentation location! 🛑
|
9
|
-
>
|
10
|
-
> See **https://typescript-eslint.io/rules/prefer-nullish-coalescing** for documentation.
|
11
|
-
|
12
|
-
The `??` nullish coalescing runtime operator allows providing a default value when dealing with `null` or `undefined`.
|
13
|
-
Because the nullish coalescing operator _only_ coalesces when the original value is `null` or `undefined`, it is much safer than relying upon logical OR operator chaining `||`, which coalesces on any _falsy_ value.
|
14
|
-
|
15
|
-
This rule reports when you may consider replacing:
|
16
|
-
|
17
|
-
- An `||` operator with `??`
|
18
|
-
- An `||=` operator with `??=`
|
19
|
-
- Ternary expressions (`?:`) that are equivalent to `||` or `??` with `??`
|
20
|
-
- Assignment expressions (`=`) that can be safely replaced by `??=`
|
21
|
-
|
22
|
-
## Examples
|
23
|
-
|
24
|
-
<Tabs>
|
25
|
-
<TabItem value="❌ Incorrect">
|
26
|
-
|
27
|
-
```ts
|
28
|
-
declare const a: string | null;
|
29
|
-
declare const b: string | null;
|
30
|
-
|
31
|
-
const c = a || b;
|
32
|
-
|
33
|
-
declare let foo: { a: string } | null;
|
34
|
-
declare function makeFoo(): { a: string };
|
35
|
-
|
36
|
-
function lazyInitializeFooByTruthiness() {
|
37
|
-
if (!foo) {
|
38
|
-
foo = makeFoo();
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
function lazyInitializeFooByNullCheck() {
|
43
|
-
if (foo == null) {
|
44
|
-
foo = makeFoo();
|
45
|
-
}
|
46
|
-
}
|
47
|
-
```
|
48
|
-
|
49
|
-
</TabItem>
|
50
|
-
<TabItem value="✅ Correct">
|
51
|
-
|
52
|
-
```ts
|
53
|
-
declare const a: string | null;
|
54
|
-
declare const b: string | null;
|
55
|
-
|
56
|
-
const c = a ?? b;
|
57
|
-
|
58
|
-
declare let foo: { a: string } | null;
|
59
|
-
declare function makeFoo(): { a: string };
|
60
|
-
|
61
|
-
function lazyInitializeFoo() {
|
62
|
-
foo ??= makeFoo();
|
63
|
-
}
|
64
|
-
```
|
65
|
-
|
66
|
-
</TabItem>
|
67
|
-
</Tabs>
|
68
|
-
|
69
|
-
:::caution
|
70
|
-
This rule will not work as expected if [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks) is not enabled.
|
71
|
-
:::
|
72
|
-
|
73
|
-
## Options
|
74
|
-
|
75
|
-
### `ignoreTernaryTests`
|
76
|
-
|
77
|
-
{/* insert option description */}
|
78
|
-
|
79
|
-
Examples of code for this rule with `{ ignoreTernaryTests: false }`:
|
80
|
-
|
81
|
-
<Tabs>
|
82
|
-
<TabItem value="❌ Incorrect">
|
83
|
-
|
84
|
-
```ts option='{ "ignoreTernaryTests": false }'
|
85
|
-
declare const a: any;
|
86
|
-
a !== undefined && a !== null ? a : 'a string';
|
87
|
-
a === undefined || a === null ? 'a string' : a;
|
88
|
-
a == undefined ? 'a string' : a;
|
89
|
-
a == null ? 'a string' : a;
|
90
|
-
|
91
|
-
declare const b: string | undefined;
|
92
|
-
b !== undefined ? b : 'a string';
|
93
|
-
b === undefined ? 'a string' : b;
|
94
|
-
b ? b : 'a string';
|
95
|
-
!b ? 'a string' : b;
|
96
|
-
|
97
|
-
declare const c: string | null;
|
98
|
-
c !== null ? c : 'a string';
|
99
|
-
c === null ? 'a string' : c;
|
100
|
-
c ? c : 'a string';
|
101
|
-
!c ? 'a string' : c;
|
102
|
-
```
|
103
|
-
|
104
|
-
</TabItem>
|
105
|
-
<TabItem value="✅ Correct">
|
106
|
-
|
107
|
-
```ts option='{ "ignoreTernaryTests": false }'
|
108
|
-
declare const a: any;
|
109
|
-
a ?? 'a string';
|
110
|
-
|
111
|
-
declare const b: string | undefined;
|
112
|
-
b ?? 'a string';
|
113
|
-
|
114
|
-
declare const c: string | null;
|
115
|
-
c ?? 'a string';
|
116
|
-
```
|
117
|
-
|
118
|
-
</TabItem>
|
119
|
-
</Tabs>
|
120
|
-
|
121
|
-
### `ignoreIfStatements`
|
122
|
-
|
123
|
-
{/* insert option description */}
|
124
|
-
|
125
|
-
Examples of code for this rule with `{ ignoreIfStatements: false }`:
|
126
|
-
|
127
|
-
<Tabs>
|
128
|
-
<TabItem value="❌ Incorrect">
|
129
|
-
|
130
|
-
```ts option='{ "ignoreIfStatements": false }'
|
131
|
-
declare let foo: { a: string } | null;
|
132
|
-
declare function makeFoo(): { a: string };
|
133
|
-
|
134
|
-
function lazyInitializeFoo1() {
|
135
|
-
if (!foo) {
|
136
|
-
foo = makeFoo();
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
function lazyInitializeFoo2() {
|
141
|
-
if (!foo) foo = makeFoo();
|
142
|
-
}
|
143
|
-
```
|
144
|
-
|
145
|
-
</TabItem>
|
146
|
-
<TabItem value="✅ Correct">
|
147
|
-
|
148
|
-
```ts option='{ "ignoreIfStatements": false }'
|
149
|
-
declare let foo: { a: string } | null;
|
150
|
-
declare function makeFoo(): { a: string };
|
151
|
-
|
152
|
-
function lazyInitializeFoo1() {
|
153
|
-
foo ??= makeFoo();
|
154
|
-
}
|
155
|
-
|
156
|
-
function lazyInitializeFoo2() {
|
157
|
-
foo ??= makeFoo();
|
158
|
-
}
|
159
|
-
```
|
160
|
-
|
161
|
-
</TabItem>
|
162
|
-
</Tabs>
|
163
|
-
|
164
|
-
### `ignoreConditionalTests`
|
165
|
-
|
166
|
-
{/* insert option description */}
|
167
|
-
|
168
|
-
Generally expressions within conditional tests intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
|
169
|
-
|
170
|
-
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
|
171
|
-
|
172
|
-
Examples of code for this rule with `{ ignoreConditionalTests: false }`:
|
173
|
-
|
174
|
-
<Tabs>
|
175
|
-
<TabItem value="❌ Incorrect">
|
176
|
-
|
177
|
-
```ts option='{ "ignoreConditionalTests": false }'
|
178
|
-
declare let a: string | null;
|
179
|
-
declare const b: string | null;
|
180
|
-
|
181
|
-
if (a || b) {
|
182
|
-
}
|
183
|
-
if ((a ||= b)) {
|
184
|
-
}
|
185
|
-
while (a || b) {}
|
186
|
-
while ((a ||= b)) {}
|
187
|
-
do {} while (a || b);
|
188
|
-
for (let i = 0; a || b; i += 1) {}
|
189
|
-
a || b ? true : false;
|
190
|
-
```
|
191
|
-
|
192
|
-
</TabItem>
|
193
|
-
<TabItem value="✅ Correct">
|
194
|
-
|
195
|
-
```ts option='{ "ignoreConditionalTests": false }'
|
196
|
-
declare let a: string | null;
|
197
|
-
declare const b: string | null;
|
198
|
-
|
199
|
-
if (a ?? b) {
|
200
|
-
}
|
201
|
-
if ((a ??= b)) {
|
202
|
-
}
|
203
|
-
while (a ?? b) {}
|
204
|
-
while ((a ??= b)) {}
|
205
|
-
do {} while (a ?? b);
|
206
|
-
for (let i = 0; a ?? b; i += 1) {}
|
207
|
-
(a ?? b) ? true : false;
|
208
|
-
```
|
209
|
-
|
210
|
-
</TabItem>
|
211
|
-
</Tabs>
|
212
|
-
|
213
|
-
### `ignoreMixedLogicalExpressions`
|
214
|
-
|
215
|
-
{/* insert option description */}
|
216
|
-
|
217
|
-
Generally expressions within mixed logical expressions intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.
|
218
|
-
|
219
|
-
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
|
220
|
-
|
221
|
-
Examples of code for this rule with `{ ignoreMixedLogicalExpressions: false }`:
|
222
|
-
|
223
|
-
<Tabs>
|
224
|
-
<TabItem value="❌ Incorrect">
|
225
|
-
|
226
|
-
```ts option='{ "ignoreMixedLogicalExpressions": false }'
|
227
|
-
declare let a: string | null;
|
228
|
-
declare const b: string | null;
|
229
|
-
declare const c: string | null;
|
230
|
-
declare const d: string | null;
|
231
|
-
|
232
|
-
a || (b && c);
|
233
|
-
a ||= b && c;
|
234
|
-
(a && b) || c || d;
|
235
|
-
a || (b && c) || d;
|
236
|
-
a || (b && c && d);
|
237
|
-
```
|
238
|
-
|
239
|
-
</TabItem>
|
240
|
-
<TabItem value="✅ Correct">
|
241
|
-
|
242
|
-
```ts option='{ "ignoreMixedLogicalExpressions": false }'
|
243
|
-
declare let a: string | null;
|
244
|
-
declare const b: string | null;
|
245
|
-
declare const c: string | null;
|
246
|
-
declare const d: string | null;
|
247
|
-
|
248
|
-
a ?? (b && c);
|
249
|
-
a ??= b && c;
|
250
|
-
(a && b) ?? c ?? d;
|
251
|
-
a ?? (b && c) ?? d;
|
252
|
-
a ?? (b && c && d);
|
253
|
-
```
|
254
|
-
|
255
|
-
</TabItem>
|
256
|
-
</Tabs>
|
257
|
-
|
258
|
-
**_NOTE:_** Errors for this specific case will be presented as suggestions (see below), instead of fixes. This is because it is not always safe to automatically convert `||` to `??` within a mixed logical expression, as we cannot tell the intended precedence of the operator. Note that by design, `??` requires parentheses when used with `&&` or `||` in the same expression.
|
259
|
-
|
260
|
-
### `ignorePrimitives`
|
261
|
-
|
262
|
-
{/* insert option description */}
|
263
|
-
|
264
|
-
If you would like to ignore expressions containing operands of certain primitive types that can be falsy then you may pass an object containing a boolean value for each primitive:
|
265
|
-
|
266
|
-
- `string: true`, ignores `null` or `undefined` unions with `string` (default: `false`).
|
267
|
-
- `number: true`, ignores `null` or `undefined` unions with `number` (default: `false`).
|
268
|
-
- `bigint: true`, ignores `null` or `undefined` unions with `bigint` (default: `false`).
|
269
|
-
- `boolean: true`, ignores `null` or `undefined` unions with `boolean` (default: `false`).
|
270
|
-
|
271
|
-
Examples of code for this rule with `{ ignorePrimitives: { string: false } }`:
|
272
|
-
|
273
|
-
<Tabs>
|
274
|
-
<TabItem value="❌ Incorrect">
|
275
|
-
|
276
|
-
```ts option='{ "ignorePrimitives": { "string": false } }'
|
277
|
-
declare const foo: string | undefined;
|
278
|
-
|
279
|
-
foo || 'a string';
|
280
|
-
```
|
281
|
-
|
282
|
-
</TabItem>
|
283
|
-
<TabItem value="✅ Correct">
|
284
|
-
|
285
|
-
```ts option='{ "ignorePrimitives": { "string": false } }'
|
286
|
-
declare const foo: string | undefined;
|
287
|
-
|
288
|
-
foo ?? 'a string';
|
289
|
-
```
|
290
|
-
|
291
|
-
</TabItem>
|
292
|
-
</Tabs>
|
293
|
-
|
294
|
-
Also, if you would like to ignore all primitives types, you can set `ignorePrimitives: true`. It is equivalent to `ignorePrimitives: { string: true, number: true, bigint: true, boolean: true }`.
|
295
|
-
|
296
|
-
### `ignoreBooleanCoercion`
|
297
|
-
|
298
|
-
{/* insert option description */}
|
299
|
-
|
300
|
-
Examples of code for this rule with `{ ignoreBooleanCoercion: false }`:
|
301
|
-
|
302
|
-
<Tabs>
|
303
|
-
<TabItem value="❌ Incorrect">
|
304
|
-
|
305
|
-
```ts option='{ "ignoreBooleanCoercion": false }'
|
306
|
-
declare const a: string | true | undefined;
|
307
|
-
declare const b: string | boolean | undefined;
|
308
|
-
|
309
|
-
const x = Boolean(a || b);
|
310
|
-
```
|
311
|
-
|
312
|
-
</TabItem>
|
313
|
-
<TabItem value="✅ Correct">
|
314
|
-
|
315
|
-
```ts option='{ "ignoreBooleanCoercion": false }'
|
316
|
-
declare const a: string | true | undefined;
|
317
|
-
declare const b: string | boolean | undefined;
|
318
|
-
|
319
|
-
const x = Boolean(a ?? b);
|
320
|
-
```
|
321
|
-
|
322
|
-
</TabItem>
|
323
|
-
</Tabs>
|
324
|
-
|
325
|
-
### `allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing`
|
326
|
-
|
327
|
-
:::danger Deprecated
|
328
|
-
|
329
|
-
This option will be removed in the next major version of typescript-eslint.
|
330
|
-
|
331
|
-
:::
|
332
|
-
|
333
|
-
{/* insert option description */}
|
334
|
-
|
335
|
-
Without `strictNullChecks`, TypeScript essentially erases `undefined` and `null` from the types. This means when this rule inspects the types from a variable, **it will not be able to tell that the variable might be `null` or `undefined`**, which essentially makes this rule useless.
|
336
|
-
|
337
|
-
You should be using `strictNullChecks` to ensure complete type-safety in your codebase.
|
338
|
-
|
339
|
-
If for some reason you cannot turn on `strictNullChecks`, but still want to use this rule - you can use this option to allow it - but know that the behavior of this rule is _undefined_ with the compiler option turned off. We will not accept bug reports if you are using this option.
|
340
|
-
|
341
|
-
## When Not To Use It
|
342
|
-
|
343
|
-
If you are not using TypeScript 3.7 (or greater), then you will not be able to use this rule, as the operator is not supported.
|
344
|
-
|
345
|
-
## Further Reading
|
346
|
-
|
347
|
-
- [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html)
|
348
|
-
- [Nullish Coalescing Operator Proposal](https://github.com/tc39/proposal-nullish-coalescing/)
|
349
|
-
- [`logical-assignment-operators`](https://eslint.org/docs/latest/rules/logical-assignment-operators)
|
@@ -1,304 +0,0 @@
|
|
1
|
-
---
|
2
|
-
description: 'Enforce using concise optional chain expressions instead of chained logical ands, negated logical ors, or empty objects.'
|
3
|
-
---
|
4
|
-
|
5
|
-
import Tabs from '@theme/Tabs';
|
6
|
-
import TabItem from '@theme/TabItem';
|
7
|
-
|
8
|
-
> 🛑 This file is source code, not the primary documentation location! 🛑
|
9
|
-
>
|
10
|
-
> See **https://typescript-eslint.io/rules/prefer-optional-chain** for documentation.
|
11
|
-
|
12
|
-
`?.` optional chain expressions provide `undefined` if an object is `null` or `undefined`.
|
13
|
-
Because the optional chain operator _only_ chains when the property value is `null` or `undefined`, it is much safer than relying upon logical AND operator chaining `&&`; which chains on any _truthy_ value.
|
14
|
-
It is also often less code to use `?.` optional chaining than `&&` truthiness checks.
|
15
|
-
|
16
|
-
This rule reports on code where an `&&` operator can be safely replaced with `?.` optional chaining.
|
17
|
-
|
18
|
-
## Examples
|
19
|
-
|
20
|
-
<Tabs>
|
21
|
-
<TabItem value="❌ Incorrect">
|
22
|
-
|
23
|
-
```ts
|
24
|
-
foo && foo.a && foo.a.b && foo.a.b.c;
|
25
|
-
foo && foo['a'] && foo['a'].b && foo['a'].b.c;
|
26
|
-
foo && foo.a && foo.a.b && foo.a.b.method && foo.a.b.method();
|
27
|
-
|
28
|
-
// With empty objects
|
29
|
-
(((foo || {}).a || {}).b || {}).c;
|
30
|
-
(((foo || {})['a'] || {}).b || {}).c;
|
31
|
-
|
32
|
-
// With negated `or`s
|
33
|
-
!foo || !foo.bar;
|
34
|
-
!foo || !foo[bar];
|
35
|
-
!foo || !foo.bar || !foo.bar.baz || !foo.bar.baz();
|
36
|
-
|
37
|
-
// this rule also supports converting chained strict nullish checks:
|
38
|
-
foo &&
|
39
|
-
foo.a != null &&
|
40
|
-
foo.a.b !== null &&
|
41
|
-
foo.a.b.c != undefined &&
|
42
|
-
foo.a.b.c.d !== undefined &&
|
43
|
-
foo.a.b.c.d.e;
|
44
|
-
```
|
45
|
-
|
46
|
-
</TabItem>
|
47
|
-
<TabItem value="✅ Correct">
|
48
|
-
|
49
|
-
```ts
|
50
|
-
foo?.a?.b?.c;
|
51
|
-
foo?.['a']?.b?.c;
|
52
|
-
foo?.a?.b?.method?.();
|
53
|
-
|
54
|
-
foo?.a?.b?.c?.d?.e;
|
55
|
-
|
56
|
-
!foo?.bar;
|
57
|
-
!foo?.[bar];
|
58
|
-
!foo?.bar?.baz?.();
|
59
|
-
```
|
60
|
-
|
61
|
-
</TabItem>
|
62
|
-
</Tabs>
|
63
|
-
|
64
|
-
## Options
|
65
|
-
|
66
|
-
In the context of the descriptions below a "loose boolean" operand is any operand that implicitly coerces the value to a boolean.
|
67
|
-
Specifically the argument of the not operator (`!loose`) or a bare value in a logical expression (`loose && looser`).
|
68
|
-
|
69
|
-
### `allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing`
|
70
|
-
|
71
|
-
{/* insert option description */}
|
72
|
-
|
73
|
-
When this option is `true`, the rule will provide an auto-fixer for cases where the return type of the expression would change. For example for the expression `!foo || foo.bar` the return type of the expression is `true | T`, however for the equivalent optional chain `foo?.bar` the return type of the expression is `undefined | T`. Thus changing the code from a logical expression to an optional chain expression has altered the type of the expression.
|
74
|
-
|
75
|
-
In some cases this distinction _may_ matter - which is why these fixers are considered unsafe - they may break the build! For example in the following code:
|
76
|
-
|
77
|
-
```ts option='{ "allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing": true }' showPlaygroundButton
|
78
|
-
declare const foo: { bar: boolean } | null | undefined;
|
79
|
-
declare function acceptsBoolean(arg: boolean): void;
|
80
|
-
|
81
|
-
// ✅ typechecks succesfully as the expression only returns `boolean`
|
82
|
-
acceptsBoolean(foo != null && foo.bar);
|
83
|
-
|
84
|
-
// ❌ typechecks UNSUCCESSFULLY as the expression returns `boolean | undefined`
|
85
|
-
acceptsBoolean(foo?.bar);
|
86
|
-
```
|
87
|
-
|
88
|
-
This style of code isn't super common - which means having this option set to `true` _should_ be safe in most codebases. However we default it to `false` due to its unsafe nature. We have provided this option for convenience because it increases the autofix cases covered by the rule. If you set option to `true` the onus is entirely on you and your team to ensure that each fix is correct and safe and that it does not break the build.
|
89
|
-
|
90
|
-
When this option is `false` unsafe cases will have suggestion fixers provided instead of auto-fixers - meaning you can manually apply the fix using your IDE tooling.
|
91
|
-
|
92
|
-
### `checkAny`
|
93
|
-
|
94
|
-
{/* insert option description */}
|
95
|
-
|
96
|
-
Examples of code for this rule with `{ checkAny: true }`:
|
97
|
-
|
98
|
-
<Tabs>
|
99
|
-
<TabItem value="❌ Incorrect">
|
100
|
-
|
101
|
-
```ts option='{ "checkAny": true }'
|
102
|
-
declare const thing: any;
|
103
|
-
|
104
|
-
thing && thing.toString();
|
105
|
-
```
|
106
|
-
|
107
|
-
</TabItem>
|
108
|
-
<TabItem value="✅ Correct">
|
109
|
-
|
110
|
-
```ts option='{ "checkAny": true }'
|
111
|
-
declare const thing: any;
|
112
|
-
|
113
|
-
thing?.toString();
|
114
|
-
```
|
115
|
-
|
116
|
-
</TabItem>
|
117
|
-
</Tabs>
|
118
|
-
|
119
|
-
### `checkUnknown`
|
120
|
-
|
121
|
-
{/* insert option description */}
|
122
|
-
|
123
|
-
Examples of code for this rule with `{ checkUnknown: true }`:
|
124
|
-
|
125
|
-
<Tabs>
|
126
|
-
<TabItem value="❌ Incorrect">
|
127
|
-
|
128
|
-
```ts option='{ "checkUnknown": true }'
|
129
|
-
declare const thing: unknown;
|
130
|
-
|
131
|
-
thing && thing.toString();
|
132
|
-
```
|
133
|
-
|
134
|
-
</TabItem>
|
135
|
-
<TabItem value="✅ Correct">
|
136
|
-
|
137
|
-
```ts option='{ "checkUnknown": true }'
|
138
|
-
declare const thing: unknown;
|
139
|
-
|
140
|
-
thing?.toString();
|
141
|
-
```
|
142
|
-
|
143
|
-
</TabItem>
|
144
|
-
</Tabs>
|
145
|
-
|
146
|
-
### `checkString`
|
147
|
-
|
148
|
-
{/* insert option description */}
|
149
|
-
|
150
|
-
Examples of code for this rule with `{ checkString: true }`:
|
151
|
-
|
152
|
-
<Tabs>
|
153
|
-
<TabItem value="❌ Incorrect">
|
154
|
-
|
155
|
-
```ts option='{ "checkString": true }'
|
156
|
-
declare const thing: string;
|
157
|
-
|
158
|
-
thing && thing.toString();
|
159
|
-
```
|
160
|
-
|
161
|
-
</TabItem>
|
162
|
-
<TabItem value="✅ Correct">
|
163
|
-
|
164
|
-
```ts option='{ "checkString": true }'
|
165
|
-
declare const thing: string;
|
166
|
-
|
167
|
-
thing?.toString();
|
168
|
-
```
|
169
|
-
|
170
|
-
</TabItem>
|
171
|
-
</Tabs>
|
172
|
-
|
173
|
-
### `checkNumber`
|
174
|
-
|
175
|
-
{/* insert option description */}
|
176
|
-
|
177
|
-
Examples of code for this rule with `{ checkNumber: true }`:
|
178
|
-
|
179
|
-
<Tabs>
|
180
|
-
<TabItem value="❌ Incorrect">
|
181
|
-
|
182
|
-
```ts option='{ "checkNumber": true }'
|
183
|
-
declare const thing: number;
|
184
|
-
|
185
|
-
thing && thing.toString();
|
186
|
-
```
|
187
|
-
|
188
|
-
</TabItem>
|
189
|
-
<TabItem value="✅ Correct">
|
190
|
-
|
191
|
-
```ts option='{ "checkNumber": true }'
|
192
|
-
declare const thing: number;
|
193
|
-
|
194
|
-
thing?.toString();
|
195
|
-
```
|
196
|
-
|
197
|
-
</TabItem>
|
198
|
-
</Tabs>
|
199
|
-
|
200
|
-
### `checkBoolean`
|
201
|
-
|
202
|
-
{/* insert option description */}
|
203
|
-
|
204
|
-
:::note
|
205
|
-
|
206
|
-
This rule intentionally ignores the following case:
|
207
|
-
|
208
|
-
```ts
|
209
|
-
declare const x: false | { a: string };
|
210
|
-
x && x.a;
|
211
|
-
!x || x.a;
|
212
|
-
```
|
213
|
-
|
214
|
-
The boolean expression narrows out the non-nullish falsy cases - so converting the chain to `x?.a` would introduce a type error.
|
215
|
-
|
216
|
-
:::
|
217
|
-
|
218
|
-
Examples of code for this rule with `{ checkBoolean: true }`:
|
219
|
-
|
220
|
-
<Tabs>
|
221
|
-
<TabItem value="❌ Incorrect">
|
222
|
-
|
223
|
-
```ts option='{ "checkBoolean": true }'
|
224
|
-
declare const thing: true;
|
225
|
-
|
226
|
-
thing && thing.toString();
|
227
|
-
```
|
228
|
-
|
229
|
-
</TabItem>
|
230
|
-
<TabItem value="✅ Correct">
|
231
|
-
|
232
|
-
```ts option='{ "checkBoolean": true }'
|
233
|
-
declare const thing: true;
|
234
|
-
|
235
|
-
thing?.toString();
|
236
|
-
```
|
237
|
-
|
238
|
-
</TabItem>
|
239
|
-
</Tabs>
|
240
|
-
|
241
|
-
### `checkBigInt`
|
242
|
-
|
243
|
-
{/* insert option description */}
|
244
|
-
|
245
|
-
Examples of code for this rule with `{ checkBigInt: true }`:
|
246
|
-
|
247
|
-
<Tabs>
|
248
|
-
<TabItem value="❌ Incorrect">
|
249
|
-
|
250
|
-
```ts option='{ "checkBigInt": true }'
|
251
|
-
declare const thing: bigint;
|
252
|
-
|
253
|
-
thing && thing.toString();
|
254
|
-
```
|
255
|
-
|
256
|
-
</TabItem>
|
257
|
-
<TabItem value="✅ Correct">
|
258
|
-
|
259
|
-
```ts option='{ "checkBigInt": true }'
|
260
|
-
declare const thing: bigint;
|
261
|
-
|
262
|
-
thing?.toString();
|
263
|
-
```
|
264
|
-
|
265
|
-
</TabItem>
|
266
|
-
</Tabs>
|
267
|
-
|
268
|
-
### `requireNullish`
|
269
|
-
|
270
|
-
{/* insert option description */}
|
271
|
-
|
272
|
-
Examples of code for this rule with `{ requireNullish: true }`:
|
273
|
-
|
274
|
-
<Tabs>
|
275
|
-
<TabItem value="❌ Incorrect">
|
276
|
-
|
277
|
-
```ts option='{ "requireNullish": true }'
|
278
|
-
declare const thing1: string | null;
|
279
|
-
thing1 && thing1.toString();
|
280
|
-
```
|
281
|
-
|
282
|
-
</TabItem>
|
283
|
-
<TabItem value="✅ Correct">
|
284
|
-
|
285
|
-
```ts option='{ "requireNullish": true }'
|
286
|
-
declare const thing1: string | null;
|
287
|
-
thing1?.toString();
|
288
|
-
|
289
|
-
declare const thing2: string;
|
290
|
-
thing2 && thing2.toString();
|
291
|
-
```
|
292
|
-
|
293
|
-
</TabItem>
|
294
|
-
</Tabs>
|
295
|
-
|
296
|
-
## When Not To Use It
|
297
|
-
|
298
|
-
If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to [trade-offs in control flow analysis](https://github.com/Microsoft/TypeScript/issues/9998), it may be difficult to enable this rule for particularly non-type-safe areas of code.
|
299
|
-
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule.
|
300
|
-
|
301
|
-
## Further Reading
|
302
|
-
|
303
|
-
- [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html)
|
304
|
-
- [Optional Chaining Proposal](https://github.com/tc39/proposal-optional-chaining/)
|