diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
index 904c7f40b7fe..5a99fe0259c6 100644
--- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
+++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx
@@ -118,6 +118,49 @@ c ?? 'a string';
+### `ignoreIfStatements`
+
+{/* insert option description */}
+
+Examples of code for this rule with `{ ignoreIfStatements: false }`:
+
+
+
+
+```ts option='{ "ignoreIfStatements": false }'
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitializeFoo1() {
+ if (!foo) {
+ foo = makeFoo();
+ }
+}
+
+function lazyInitializeFoo2() {
+ if (!foo) foo = makeFoo();
+}
+```
+
+
+
+
+```ts option='{ "ignoreIfStatements": false }'
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitializeFoo1() {
+ foo ??= makeFoo();
+}
+
+function lazyInitializeFoo2() {
+ foo ??= makeFoo();
+}
+```
+
+
+
+
### `ignoreConditionalTests`
{/* insert option description */}
diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts
index 8f49f74089a8..b05e43d0431e 100644
--- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts
+++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts
@@ -40,6 +40,7 @@ export type Options = [
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
ignoreBooleanCoercion?: boolean;
ignoreConditionalTests?: boolean;
+ ignoreIfStatements?: boolean;
ignoreMixedLogicalExpressions?: boolean;
ignorePrimitives?:
| {
@@ -102,6 +103,11 @@ export default createRule({
description:
'Whether to ignore cases that are located within a conditional test.',
},
+ ignoreIfStatements: {
+ type: 'boolean',
+ description:
+ 'Whether to ignore any if statements that could be simplified by using the nullish coalescing operator.',
+ },
ignoreMixedLogicalExpressions: {
type: 'boolean',
description:
@@ -154,6 +160,7 @@ export default createRule({
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
ignoreBooleanCoercion: false,
ignoreConditionalTests: true,
+ ignoreIfStatements: false,
ignoreMixedLogicalExpressions: false,
ignorePrimitives: {
bigint: false,
@@ -171,6 +178,7 @@ export default createRule({
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing,
ignoreBooleanCoercion,
ignoreConditionalTests,
+ ignoreIfStatements,
ignoreMixedLogicalExpressions,
ignorePrimitives,
ignoreTernaryTests,
@@ -516,7 +524,7 @@ export default createRule({
}
},
IfStatement(node: TSESTree.IfStatement): void {
- if (node.alternate != null) {
+ if (ignoreIfStatements || node.alternate != null) {
return;
}
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 46ff002cd623..b3d8543af57d 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
@@ -102,6 +102,46 @@ c ?? 'a string';
exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 5`] = `
"Incorrect
+Options: { "ignoreIfStatements": false }
+
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitializeFoo1() {
+ if (!foo) {
+ ~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??=\`) instead of an assignment expression, as it is simpler to read.
+ foo = makeFoo();
+~~~~~~~~~~~~~~~~~~~~
+ }
+~~~
+}
+
+function lazyInitializeFoo2() {
+ if (!foo) foo = makeFoo();
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using nullish coalescing operator (\`??=\`) instead of an assignment expression, as it is simpler to read.
+}
+"
+`;
+
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 6`] = `
+"Correct
+Options: { "ignoreIfStatements": false }
+
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitializeFoo1() {
+ foo ??= makeFoo();
+}
+
+function lazyInitializeFoo2() {
+ foo ??= makeFoo();
+}
+"
+`;
+
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 7`] = `
+"Incorrect
Options: { "ignoreConditionalTests": false }
declare let a: string | null;
@@ -126,7 +166,7 @@ a || b ? true : false;
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 6`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 8`] = `
"Correct
Options: { "ignoreConditionalTests": false }
@@ -145,7 +185,7 @@ for (let i = 0; a ?? b; i += 1) {}
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 7`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 9`] = `
"Incorrect
Options: { "ignoreMixedLogicalExpressions": false }
@@ -169,7 +209,7 @@ a || (b && c && d);
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 8`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 10`] = `
"Correct
Options: { "ignoreMixedLogicalExpressions": false }
@@ -186,7 +226,7 @@ a ?? (b && c && d);
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 9`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 11`] = `
"Incorrect
Options: { "ignorePrimitives": { "string": false } }
@@ -197,7 +237,7 @@ foo || 'a string';
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 10`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 12`] = `
"Correct
Options: { "ignorePrimitives": { "string": false } }
@@ -207,7 +247,7 @@ foo ?? 'a string';
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 11`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 13`] = `
"Incorrect
Options: { "ignoreBooleanCoercion": false }
@@ -219,7 +259,7 @@ const x = Boolean(a || b);
"
`;
-exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 12`] = `
+exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 14`] = `
"Correct
Options: { "ignoreBooleanCoercion": false }
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 b17d4753f074..0926a839ee38 100644
--- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts
+++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts
@@ -518,6 +518,30 @@ x?.a ? y?.a : 'foo'
code,
options: [{ ignoreTernaryTests: false }] as const,
})),
+ {
+ code: `
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitialize() {
+ if (!foo) {
+ foo = makeFoo();
+ }
+}
+ `,
+ options: [{ ignoreIfStatements: true }],
+ },
+ {
+ code: `
+declare let foo: { a: string } | null;
+declare function makeFoo(): { a: string };
+
+function lazyInitialize() {
+ if (!foo) foo = makeFoo();
+}
+ `,
+ options: [{ ignoreIfStatements: true }],
+ },
// ignoreConditionalTests
...nullishTypeTest((nullish, type, equals) => ({
diff --git a/packages/eslint-plugin/tests/schema-snapshots/prefer-nullish-coalescing.shot b/packages/eslint-plugin/tests/schema-snapshots/prefer-nullish-coalescing.shot
index ea441036f3a0..7c3b288ca1b4 100644
--- a/packages/eslint-plugin/tests/schema-snapshots/prefer-nullish-coalescing.shot
+++ b/packages/eslint-plugin/tests/schema-snapshots/prefer-nullish-coalescing.shot
@@ -20,6 +20,10 @@ exports[`Rule schemas should be convertible to TS types for documentation purpos
"description": "Whether to ignore cases that are located within a conditional test.",
"type": "boolean"
},
+ "ignoreIfStatements": {
+ "description": "Whether to ignore any if statements that could be simplified by using the nullish coalescing operator.",
+ "type": "boolean"
+ },
"ignoreMixedLogicalExpressions": {
"description": "Whether to ignore any logical or expressions that are part of a mixed logical expression (with \`&&\`).",
"type": "boolean"
@@ -76,6 +80,8 @@ type Options = [
ignoreBooleanCoercion?: boolean;
/** Whether to ignore cases that are located within a conditional test. */
ignoreConditionalTests?: boolean;
+ /** Whether to ignore any if statements that could be simplified by using the nullish coalescing operator. */
+ ignoreIfStatements?: boolean;
/** Whether to ignore any logical or expressions that are part of a mixed logical expression (with \`&&\`). */
ignoreMixedLogicalExpressions?: boolean;
/** Whether to ignore all (\`true\`) or some (an object with properties) primitive types. */