diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
index 2de5f81c71d7..87cf88527046 100644
--- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
+++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
@@ -28,46 +28,48 @@ This rule will not work as expected if [`strictNullChecks`](https://www.typescri
{/* insert option description */}
-Incorrect code for `ignoreTernaryTests: false`, and correct code for `ignoreTernaryTests: true`:
-
-```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
-const foo: any = 'bar';
-foo !== undefined && foo !== null ? foo : 'a string';
-foo === undefined || foo === null ? 'a string' : foo;
-foo == undefined ? 'a string' : foo;
-foo == null ? 'a string' : foo;
-
-const foo: string | undefined = 'bar';
-foo !== undefined ? foo : 'a string';
-foo === undefined ? 'a string' : foo;
-
-const foo: string | null = 'bar';
-foo !== null ? foo : 'a string';
-foo ? foo : 'a string';
-foo === null ? 'a string' : foo;
-!foo ? 'a string' : foo;
+Examples of code for this rule with `{ ignoreTernaryTests: false }`:
+
+
+
+
+```ts option='{ "ignoreTernaryTests": false }'
+declare const a: any;
+a !== undefined && a !== null ? a : 'a string';
+a === undefined || a === null ? 'a string' : a;
+a == undefined ? 'a string' : a;
+a == null ? 'a string' : a;
+
+declare const b: string | undefined;
+b !== undefined ? b : 'a string';
+b === undefined ? 'a string' : b;
+b ? b : 'a string';
+!b ? 'a string' : b;
+
+declare const c: string | null;
+c !== null ? c : 'a string';
+c === null ? 'a string' : c;
+c ? c : 'a string';
+!c ? 'a string' : c;
```
-Correct code for `ignoreTernaryTests: false`:
+
+
-```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton
-const foo: any = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
+```ts option='{ "ignoreTernaryTests": false }'
+declare const a: any;
+a ?? 'a string';
-const foo: string | undefined = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
+declare const b: string | undefined;
+b ?? 'a string';
-const foo: string | null = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
+declare const c: string | null;
+c ?? 'a string';
```
+
+
+
### `ignoreConditionalTests`
{/* insert option description */}
@@ -76,9 +78,12 @@ Generally expressions within conditional tests intentionally use the falsy fallt
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
-Incorrect code for `ignoreConditionalTests: false`, and correct code for `ignoreConditionalTests: true`:
+Examples of code for this rule with `{ ignoreConditionalTests: false }`:
+
+
+
-```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
+```ts option='{ "ignoreConditionalTests": false }'
declare const a: string | null;
declare const b: string | null;
@@ -93,9 +98,10 @@ for (let i = 0; a || b; i += 1) {}
a || b ? true : false;
```
-Correct code for `ignoreConditionalTests: false`:
+
+
-```ts option='{ "ignoreConditionalTests": false }' showPlaygroundButton
+```ts option='{ "ignoreConditionalTests": false }'
declare const a: string | null;
declare const b: string | null;
@@ -110,6 +116,9 @@ for (let i = 0; a ?? b; i += 1) {}
(a ?? b) ? true : false;
```
+
+
+
### `ignoreMixedLogicalExpressions`
{/* insert option description */}
@@ -118,9 +127,12 @@ Generally expressions within mixed logical expressions intentionally use the fal
If you're looking to enforce stricter conditional tests, you should consider using the `strict-boolean-expressions` rule.
-Incorrect code for `ignoreMixedLogicalExpressions: false`, and correct code for `ignoreMixedLogicalExpressions: true`:
+Examples of code for this rule with `{ ignoreMixedLogicalExpressions: false }`:
+
+
+
-```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
+```ts option='{ "ignoreMixedLogicalExpressions": false }'
declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
@@ -133,9 +145,10 @@ a || (b && c) || d;
a || (b && c && d);
```
-Correct code for `ignoreMixedLogicalExpressions: false`:
+
+
-```ts option='{ "ignoreMixedLogicalExpressions": false }' showPlaygroundButton
+```ts option='{ "ignoreMixedLogicalExpressions": false }'
declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
@@ -148,6 +161,9 @@ a ?? (b && c) ?? d;
a ?? (b && c && d);
```
+
+
+
**_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.
### `ignorePrimitives`
@@ -156,49 +172,65 @@ a ?? (b && c && d);
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:
-- `string: true`, ignores `null` or `undefined` unions with `string` (default: false).
-- `number: true`, ignores `null` or `undefined` unions with `number` (default: false).
-- `bigint: true`, ignores `null` or `undefined` unions with `bigint` (default: false).
-- `boolean: true`, ignores `null` or `undefined` unions with `boolean` (default: false).
+- `string: true`, ignores `null` or `undefined` unions with `string` (default: `false`).
+- `number: true`, ignores `null` or `undefined` unions with `number` (default: `false`).
+- `bigint: true`, ignores `null` or `undefined` unions with `bigint` (default: `false`).
+- `boolean: true`, ignores `null` or `undefined` unions with `boolean` (default: `false`).
-Incorrect code for `ignorePrimitives: { string: false }`, and correct code for `ignorePrimitives: { string: true }`:
+Examples of code for this rule with `{ ignorePrimitives: { string: false } }`:
+
+
+
+
+```ts option='{ "ignorePrimitives": { "string": false } }'
+declare const foo: string | undefined;
-```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
-const foo: string | undefined = 'bar';
foo || 'a string';
```
-Correct code for both `ignorePrimitives: { string: false }` and `ignorePrimitives: { string: true }`:
+
+
+
+```ts option='{ "ignorePrimitives": { "string": false } }'
+declare const foo: string | undefined;
-```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton
-const foo: string | undefined = 'bar';
foo ?? 'a string';
```
+
+
+
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 }`.
### `ignoreBooleanCoercion`
{/* insert option description */}
-Incorrect code for `ignoreBooleanCoercion: false`, and correct code for `ignoreBooleanCoercion: true`:
+Examples of code for this rule with `{ ignoreBooleanCoercion: false }`:
+
+
+
-```ts option='{ "ignoreBooleanCoercion": true }' showPlaygroundButton
-let a: string | true | undefined;
-let b: string | boolean | undefined;
+```ts option='{ "ignoreBooleanCoercion": false }'
+declare const a: string | true | undefined;
+declare const b: string | boolean | undefined;
const x = Boolean(a || b);
```
-Correct code for `ignoreBooleanCoercion: false`:
+
+
-```ts option='{ "ignoreBooleanCoercion": false }' showPlaygroundButton
-let a: string | true | undefined;
-let b: string | boolean | undefined;
+```ts option='{ "ignoreBooleanCoercion": false }'
+declare const a: string | true | undefined;
+declare const b: string | boolean | undefined;
const x = Boolean(a ?? b);
```
+
+
+
### `allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing`
:::danger Deprecated
diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot
index aeaefe9dc5ff..124ed091013c 100644
--- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot
+++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot
@@ -1,53 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 1`] = `
-"Options: { "ignoreTernaryTests": false }
-
-const foo: any = 'bar';
-foo !== undefined && foo !== null ? foo : 'a string';
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
-foo === undefined || foo === null ? 'a string' : foo;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
-foo == undefined ? 'a string' : foo;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
-foo == null ? 'a string' : foo;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
-
-const foo: string | undefined = 'bar';
-foo !== undefined ? foo : 'a string';
-foo === undefined ? 'a string' : foo;
-
-const foo: string | null = 'bar';
-foo !== null ? foo : 'a string';
-foo ? foo : 'a string';
-foo === null ? 'a string' : foo;
-!foo ? 'a string' : foo;
+"Incorrect
+Options: { "ignoreTernaryTests": false }
+
+declare const a: any;
+a !== undefined && a !== null ? a : 'a string';
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+a === undefined || a === null ? 'a string' : a;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+a == undefined ? 'a string' : a;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+a == null ? 'a string' : a;
+~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+
+declare const b: string | undefined;
+b !== undefined ? b : 'a string';
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+b === undefined ? 'a string' : b;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+b ? b : 'a string';
+~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+!b ? 'a string' : b;
+~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+
+declare const c: string | null;
+c !== null ? c : 'a string';
+~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+c === null ? 'a string' : c;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+c ? c : 'a string';
+~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
+!c ? 'a string' : c;
+~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??\`) instead of a ternary expression, as it is simpler to read.
"
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 2`] = `
-"Options: { "ignoreTernaryTests": false }
+"Correct
+Options: { "ignoreTernaryTests": false }
-const foo: any = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
+declare const a: any;
+a ?? 'a string';
-const foo: string | undefined = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
+declare const b: string | undefined;
+b ?? 'a string';
-const foo: string | null = 'bar';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
-foo ?? 'a string';
+declare const c: string | null;
+c ?? 'a string';
"
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 3`] = `
-"Options: { "ignoreConditionalTests": false }
+"Incorrect
+Options: { "ignoreConditionalTests": false }
declare const a: string | null;
declare const b: string | null;
@@ -70,7 +76,8 @@ a || b ? true : false;
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 4`] = `
-"Options: { "ignoreConditionalTests": false }
+"Correct
+Options: { "ignoreConditionalTests": false }
declare const a: string | null;
declare const b: string | null;
@@ -88,7 +95,8 @@ for (let i = 0; a ?? b; i += 1) {}
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 5`] = `
-"Options: { "ignoreMixedLogicalExpressions": false }
+"Incorrect
+Options: { "ignoreMixedLogicalExpressions": false }
declare const a: string | null;
declare const b: string | null;
@@ -110,7 +118,8 @@ a || (b && c && d);
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 6`] = `
-"Options: { "ignoreMixedLogicalExpressions": false }
+"Correct
+Options: { "ignoreMixedLogicalExpressions": false }
declare const a: string | null;
declare const b: string | null;
@@ -126,36 +135,44 @@ a ?? (b && c && d);
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 7`] = `
-"Options: { "ignorePrimitives": { "string": true } }
+"Incorrect
+Options: { "ignorePrimitives": { "string": false } }
+
+declare const foo: string | undefined;
-const foo: string | undefined = 'bar';
foo || 'a string';
+ ~~ Prefer using nullish coalescing operator (\`??\`) instead of a logical or (\`||\`), as it is a safer operator.
"
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 8`] = `
-"Options: { "ignorePrimitives": { "string": true } }
+"Correct
+Options: { "ignorePrimitives": { "string": false } }
+
+declare const foo: string | undefined;
-const foo: string | undefined = 'bar';
foo ?? 'a string';
"
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 9`] = `
-"Options: { "ignoreBooleanCoercion": true }
+"Incorrect
+Options: { "ignoreBooleanCoercion": false }
-let a: string | true | undefined;
-let b: string | boolean | undefined;
+declare const a: string | true | undefined;
+declare const b: string | boolean | undefined;
const x = Boolean(a || b);
+ ~~ Prefer using nullish coalescing operator (\`??\`) instead of a logical or (\`||\`), as it is a safer operator.
"
`;
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 10`] = `
-"Options: { "ignoreBooleanCoercion": false }
+"Correct
+Options: { "ignoreBooleanCoercion": false }
-let a: string | true | undefined;
-let b: string | boolean | undefined;
+declare const a: string | true | undefined;
+declare const b: string | boolean | undefined;
const x = Boolean(a ?? b);
"
diff --git a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts
index a9ad05c5cef5..99cca5c7369c 100644
--- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts
+++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts
@@ -154,11 +154,11 @@ declare let x: string | undefined | null;
x !== null ? x : y;
`,
`
-declare let x: string | null | any;
+declare let x: any;
x === null ? x : y;
`,
`
-declare let x: string | null | unknown;
+declare let x: unknown;
x === null ? x : y;
`,
`