From 3d9cb2e1c7842f9f8a49c56d1f13a53d529c122e Mon Sep 17 00:00:00 2001 From: Olivier Zalmanski <88216225+OlivierZal@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:51:56 +0100 Subject: [PATCH 1/5] docs(eslint-plugin): [prefer-nullish-coalescing] streamline code examples --- .../docs/rules/prefer-nullish-coalescing.mdx | 94 ++++++++++++------- .../prefer-nullish-coalescing.shot | 43 +++++---- 2 files changed, 85 insertions(+), 52 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx index be44bfe11d88..4a7321e5a730 100644 --- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx +++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx @@ -28,9 +28,12 @@ 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`: +Examples of code for this rule with `{ ignoreTernaryTests: false }`: -```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton + + + +```ts option='{ "ignoreTernaryTests": false }' const foo: any = 'bar'; foo !== undefined && foo !== null ? foo : 'a string'; foo === undefined || foo === null ? 'a string' : foo; @@ -48,26 +51,23 @@ foo === null ? 'a string' : foo; !foo ? 'a string' : foo; ``` -Correct code for `ignoreTernaryTests: false`: + + -```ts option='{ "ignoreTernaryTests": false }' showPlaygroundButton +```ts option='{ "ignoreTernaryTests": false }' const foo: any = 'bar'; foo ?? 'a string'; -foo ?? 'a string'; -foo ?? 'a string'; -foo ?? 'a string'; const foo: string | undefined = 'bar'; foo ?? 'a string'; -foo ?? 'a string'; const foo: string | null = 'bar'; foo ?? 'a string'; -foo ?? 'a string'; -foo ?? 'a string'; -foo ?? 'a string'; ``` + + + ### `ignoreConditionalTests` {/* insert option description */} @@ -76,9 +76,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 +96,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 +114,9 @@ for (let i = 0; a ?? b; i += 1) {} (a ?? b) ? true : false; ``` + + + ### `ignoreMixedLogicalExpressions` {/* insert option description */} @@ -118,9 +125,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 +143,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 +159,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,25 +170,32 @@ 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": true } }' showPlaygroundButton -const foo: string | undefined = 'bar'; + + + +```ts option='{ "ignorePrimitives": { "string": false } }' +let foo: string | undefined; foo || 'a string'; ``` -Correct code for both `ignorePrimitives: { string: false }` and `ignorePrimitives: { string: true }`: + + -```ts option='{ "ignorePrimitives": { "string": true } }' showPlaygroundButton -const foo: string | undefined = 'bar'; +```ts option='{ "ignorePrimitives": { "string": false } }' +let foo: string | undefined; 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` @@ -183,24 +204,31 @@ Also, if you would like to ignore all primitives types, you can set `ignorePrimi Whether to ignore expressions that coerce a value into a boolean: `Boolean(...)`. -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 + + + +```ts option='{ "ignoreBooleanCoercion": false }' let a: string | true | undefined; let b: string | boolean | undefined; const x = Boolean(a || b); ``` -Correct code for `ignoreBooleanCoercion: false`: + + -```ts option='{ "ignoreBooleanCoercion": false }' showPlaygroundButton +```ts option='{ "ignoreBooleanCoercion": false }' let a: string | true | undefined; let 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..83ec7999931e 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,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint output 1`] = ` -"Options: { "ignoreTernaryTests": false } +"Incorrect +Options: { "ignoreTernaryTests": false } const foo: any = 'bar'; foo !== undefined && foo !== null ? foo : 'a string'; @@ -26,28 +27,23 @@ foo === null ? 'a string' : foo; `; 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'; const foo: string | undefined = 'bar'; foo ?? 'a string'; -foo ?? 'a string'; const foo: string | null = 'bar'; foo ?? 'a string'; -foo ?? 'a string'; -foo ?? 'a string'; -foo ?? '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 +66,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 +85,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 +108,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,33 +125,39 @@ 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 } } -const foo: string | undefined = 'bar'; +let foo: string | undefined; 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 } } -const foo: string | undefined = 'bar'; +let foo: string | undefined; 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; 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; From a20c5fad1403692d11d57b6ae1806f16b644acab Mon Sep 17 00:00:00 2001 From: Olivier Zalmanski <88216225+OlivierZal@users.noreply.github.com> Date: Sat, 1 Feb 2025 11:21:40 +0100 Subject: [PATCH 2/5] make examples consistent --- .../docs/rules/prefer-nullish-coalescing.mdx | 24 +++++++++++++------ .../prefer-nullish-coalescing.shot | 24 +++++++++++++------ .../rules/prefer-nullish-coalescing.test.ts | 4 ++-- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx index 4a7321e5a730..f0b2a236b66a 100644 --- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx +++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx @@ -34,20 +34,25 @@ Examples of code for this rule with `{ ignoreTernaryTests: false }`: ```ts option='{ "ignoreTernaryTests": false }' -const foo: any = 'bar'; +declare const foo: any; + 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'; +declare const foo: string | undefined; + foo !== undefined ? foo : 'a string'; foo === undefined ? 'a string' : foo; +foo ? foo : 'a string'; +!foo ? 'a string' : foo; + +declare const foo: string | null; -const foo: string | null = 'bar'; foo !== null ? foo : 'a string'; -foo ? foo : 'a string'; foo === null ? 'a string' : foo; +foo ? foo : 'a string'; !foo ? 'a string' : foo; ``` @@ -55,13 +60,16 @@ foo === null ? 'a string' : foo; ```ts option='{ "ignoreTernaryTests": false }' -const foo: any = 'bar'; +declare const foo: any; + foo ?? 'a string'; -const foo: string | undefined = 'bar'; +declare const foo: string | undefined; + foo ?? 'a string'; -const foo: string | null = 'bar'; +declare const foo: string | null; + foo ?? 'a string'; ``` @@ -182,6 +190,7 @@ Examples of code for this rule with `{ ignorePrimitives: { string: false } }`: ```ts option='{ "ignorePrimitives": { "string": false } }' let foo: string | undefined; + foo || 'a string'; ``` @@ -190,6 +199,7 @@ foo || 'a string'; ```ts option='{ "ignorePrimitives": { "string": false } }' let foo: string | undefined; + foo ?? 'a string'; ``` 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 83ec7999931e..bce42640ea59 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 @@ -4,7 +4,8 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Incorrect Options: { "ignoreTernaryTests": false } -const foo: any = 'bar'; +declare const foo: any; + 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; @@ -14,14 +15,18 @@ foo == undefined ? 'a string' : foo; 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'; +declare const foo: string | undefined; + foo !== undefined ? foo : 'a string'; foo === undefined ? 'a string' : foo; +foo ? foo : 'a string'; +!foo ? 'a string' : foo; + +declare const foo: string | null; -const foo: string | null = 'bar'; foo !== null ? foo : 'a string'; -foo ? foo : 'a string'; foo === null ? 'a string' : foo; +foo ? foo : 'a string'; !foo ? 'a string' : foo; " `; @@ -30,13 +35,16 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Correct Options: { "ignoreTernaryTests": false } -const foo: any = 'bar'; +declare const foo: any; + foo ?? 'a string'; -const foo: string | undefined = 'bar'; +declare const foo: string | undefined; + foo ?? 'a string'; -const foo: string | null = 'bar'; +declare const foo: string | null; + foo ?? 'a string'; " `; @@ -129,6 +137,7 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint Options: { "ignorePrimitives": { "string": false } } let foo: string | undefined; + foo || 'a string'; ~~ Prefer using nullish coalescing operator (\`??\`) instead of a logical or (\`||\`), as it is a safer operator. " @@ -139,6 +148,7 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint Options: { "ignorePrimitives": { "string": false } } let foo: string | undefined; + foo ?? 'a string'; " `; 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 51442dbc7467..51b3855b9a59 100644 --- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts @@ -118,11 +118,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; `, ` From acb35a8a7a63dfcaeeef1f3b2466ed22610e1d7e Mon Sep 17 00:00:00 2001 From: Olivier Zalmanski <88216225+OlivierZal@users.noreply.github.com> Date: Sun, 2 Feb 2025 23:20:46 +0100 Subject: [PATCH 3/5] fix examples --- .../docs/rules/prefer-nullish-coalescing.mdx | 58 +++++++------- .../prefer-nullish-coalescing.shot | 76 ++++++++++--------- 2 files changed, 65 insertions(+), 69 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx index f0b2a236b66a..14e4ae26b66f 100644 --- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx +++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx @@ -34,43 +34,37 @@ Examples of code for this rule with `{ ignoreTernaryTests: false }`: ```ts option='{ "ignoreTernaryTests": false }' -declare const foo: any; +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; -foo !== undefined && foo !== null ? foo : 'a string'; -foo === undefined || foo === null ? 'a string' : foo; -foo == undefined ? 'a string' : foo; -foo == null ? 'a string' : foo; - -declare const foo: string | undefined; - -foo !== undefined ? foo : 'a string'; -foo === undefined ? 'a string' : foo; -foo ? foo : 'a string'; -!foo ? 'a string' : foo; - -declare const foo: string | null; - -foo !== null ? foo : 'a string'; -foo === null ? 'a string' : foo; -foo ? foo : 'a string'; -!foo ? 'a string' : foo; +declare const c: string | null; +c !== null ? c : 'a string'; +c === null ? 'a string' : c; +c ? c : 'a string'; +!c ? 'a string' : c; ``` ```ts option='{ "ignoreTernaryTests": false }' -declare const foo: any; - -foo ?? 'a string'; - -declare const foo: string | undefined; - -foo ?? 'a string'; +declare const a: any; +a ?? 'a string'; -declare const foo: string | null; +declare const b: string | undefined; +b ?? 'a string'; -foo ?? 'a string'; +declare const c: string | null; +c ?? 'a string'; ``` @@ -220,8 +214,8 @@ Examples of code for this rule with `{ ignoreBooleanCoercion: false }`: ```ts option='{ "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); ``` @@ -230,8 +224,8 @@ const x = Boolean(a || b); ```ts option='{ "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/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-nullish-coalescing.shot index bce42640ea59..888e45ccdb3c 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 @@ -4,30 +4,35 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Incorrect Options: { "ignoreTernaryTests": false } -declare const foo: any; - -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. - -declare const foo: string | undefined; - -foo !== undefined ? foo : 'a string'; -foo === undefined ? 'a string' : foo; -foo ? foo : 'a string'; -!foo ? 'a string' : foo; - -declare const foo: string | null; - -foo !== null ? foo : 'a string'; -foo === null ? 'a string' : foo; -foo ? foo : 'a string'; -!foo ? 'a string' : foo; +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. " `; @@ -35,17 +40,14 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Correct Options: { "ignoreTernaryTests": false } -declare const foo: any; +declare const a: any; +a ?? 'a string'; -foo ?? 'a string'; +declare const b: string | undefined; +b ?? 'a string'; -declare const foo: string | undefined; - -foo ?? 'a string'; - -declare const foo: string | null; - -foo ?? 'a string'; +declare const c: string | null; +c ?? 'a string'; " `; @@ -157,8 +159,8 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "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. @@ -169,8 +171,8 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "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); " From f891ea7c848958ac8e97dfb030be34f152a1fac6 Mon Sep 17 00:00:00 2001 From: Olivier Zalmanski <88216225+OlivierZal@users.noreply.github.com> Date: Sun, 2 Feb 2025 23:23:09 +0100 Subject: [PATCH 4/5] fix examples 2 --- .../eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx index 14e4ae26b66f..b2dc6a1c4634 100644 --- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx +++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.mdx @@ -183,7 +183,7 @@ Examples of code for this rule with `{ ignorePrimitives: { string: false } }`: ```ts option='{ "ignorePrimitives": { "string": false } }' -let foo: string | undefined; +declare const foo: string | undefined; foo || 'a string'; ``` @@ -192,7 +192,7 @@ foo || 'a string'; ```ts option='{ "ignorePrimitives": { "string": false } }' -let foo: string | undefined; +declare const foo: string | undefined; foo ?? 'a string'; ``` From a26a25acaa2c82bc9cdecd4ff904ded8135a02c2 Mon Sep 17 00:00:00 2001 From: Olivier Zalmanski <88216225+OlivierZal@users.noreply.github.com> Date: Sun, 2 Feb 2025 23:24:03 +0100 Subject: [PATCH 5/5] update snapshots --- .../prefer-nullish-coalescing.shot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 888e45ccdb3c..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 @@ -138,7 +138,7 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Incorrect Options: { "ignorePrimitives": { "string": false } } -let foo: string | undefined; +declare const foo: string | undefined; foo || 'a string'; ~~ Prefer using nullish coalescing operator (\`??\`) instead of a logical or (\`||\`), as it is a safer operator. @@ -149,7 +149,7 @@ exports[`Validating rule docs prefer-nullish-coalescing.mdx code examples ESLint "Correct Options: { "ignorePrimitives": { "string": false } } -let foo: string | undefined; +declare const foo: string | undefined; foo ?? 'a string'; "