From 5f6d84ccbd1f7850afef757637175bbad301759b Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:37:32 -0600 Subject: [PATCH 1/2] downgrade nuc fix to suggestion --- .../src/rules/no-unnecessary-condition.ts | 15 +- .../rules/no-unnecessary-condition.test.ts | 659 +++++++++++++++--- 2 files changed, 558 insertions(+), 116 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 88c5e42f0b53..f23495cb8b3f 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -152,6 +152,7 @@ export type MessageId = | 'neverOptionalChain' | 'noOverlapBooleanExpression' | 'noStrictNullCheck' + | 'suggestRemoveOptionalChain' | 'typeGuardAlreadyIsType'; export default createRule({ @@ -164,7 +165,7 @@ export default createRule({ recommended: 'strict', requiresTypeChecking: true, }, - fixable: 'code', + hasSuggestions: true, messages: { alwaysFalsy: 'Unnecessary conditional, value is always falsy.', alwaysFalsyFunc: @@ -184,6 +185,7 @@ export default createRule({ 'Unnecessary conditional, the types have no overlap.', noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.', + suggestRemoveOptionalChain: 'Replace `?.` with `.`', typeGuardAlreadyIsType: 'Unnecessary conditional, expression already has the type being checked by the {{typeGuardOrAssertionFunction}}.', }, @@ -863,9 +865,14 @@ export default createRule({ loc: questionDotOperator.loc, node, messageId: 'neverOptionalChain', - fix(fixer) { - return fixer.replaceText(questionDotOperator, fix); - }, + suggest: [ + { + messageId: 'suggestRemoveOptionalChain', + fix(fixer) { + return fixer.replaceText(questionDotOperator, fix); + }, + }, + ], }); } diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index d989188f7c36..22bb2f46c152 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -1931,16 +1931,29 @@ if (x[0]?.foo) { } `, errors: [ - { column: 5, line: 3, messageId: 'alwaysTruthy' }, - { column: 9, line: 5, messageId: 'neverOptionalChain' }, - ], - output: ` + { + column: 5, + line: 3, + messageId: 'alwaysTruthy', + }, + { + column: 9, + line: 5, + messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` const x = [{}] as [{ foo: string }]; if (x[0]) { } if (x[0].foo) { } `, + }, + ], + }, + ], }, { // Shouldn't mistake this for an array indexing case @@ -2130,6 +2143,20 @@ foo endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = { bar: true }; +foo.bar; +foo ?. bar; +foo ?. + bar; +foo + ?. bar; + `, + }, + ], }, { column: 5, @@ -2137,6 +2164,20 @@ foo endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = { bar: true }; +foo?.bar; +foo . bar; +foo ?. + bar; +foo + ?. bar; + `, + }, + ], }, { column: 5, @@ -2144,6 +2185,20 @@ foo endLine: 5, line: 5, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = { bar: true }; +foo?.bar; +foo ?. bar; +foo . + bar; +foo + ?. bar; + `, + }, + ], }, { column: 3, @@ -2151,17 +2206,22 @@ foo endLine: 8, line: 8, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` let foo = { bar: true }; -foo.bar; -foo . bar; -foo . +foo?.bar; +foo ?. bar; +foo ?. bar; foo . bar; `, + }, + ], + }, + ], }, { code: noFormat` @@ -2180,6 +2240,20 @@ foo endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo(); +foo ?. (); +foo ?. + (); +foo + ?. (); + `, + }, + ], }, { column: 5, @@ -2187,6 +2261,20 @@ foo endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo?.(); +foo (); +foo ?. + (); +foo + ?. (); + `, + }, + ], }, { column: 5, @@ -2194,6 +2282,20 @@ foo endLine: 5, line: 5, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo?.(); +foo ?. (); +foo${' '} + (); +foo + ?. (); + `, + }, + ], }, { column: 3, @@ -2201,17 +2303,22 @@ foo endLine: 8, line: 8, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` let foo = () => {}; -foo(); -foo (); -foo${' '} +foo?.(); +foo ?. (); +foo ?. (); foo (); `, + }, + ], + }, + ], }, { code: noFormat` @@ -2230,6 +2337,20 @@ foo endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo(bar); +foo ?. (bar); +foo ?. + (bar); +foo + ?. (bar); + `, + }, + ], }, { column: 5, @@ -2237,6 +2358,20 @@ foo endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo?.(bar); +foo (bar); +foo ?. + (bar); +foo + ?. (bar); + `, + }, + ], }, { column: 5, @@ -2244,6 +2379,20 @@ foo endLine: 5, line: 5, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +let foo = () => {}; +foo?.(bar); +foo ?. (bar); +foo${' '} + (bar); +foo + ?. (bar); + `, + }, + ], }, { column: 3, @@ -2251,17 +2400,22 @@ foo endLine: 8, line: 8, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` let foo = () => {}; -foo(bar); -foo (bar); -foo${' '} +foo?.(bar); +foo ?. (bar); +foo ?. (bar); foo (bar); `, + }, + ], + }, + ], }, { code: 'const foo = [1, 2, 3]?.[0];', @@ -2272,9 +2426,14 @@ foo endLine: 1, line: 1, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: 'const foo = [1, 2, 3][0];', + }, + ], }, ], - output: 'const foo = [1, 2, 3][0];', }, { code: ` @@ -2288,12 +2447,17 @@ x?.a?.b; endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const x: { a?: { b: string } }; x.a?.b; `, + }, + ], + }, + ], }, { code: ` @@ -2307,12 +2471,17 @@ x.a?.b?.c; endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const x: { a: { b?: { c: string } } }; x.a.b?.c; `, + }, + ], + }, + ], }, { code: ` @@ -2326,12 +2495,17 @@ x?.a; endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` let x: { a?: string }; x.a; `, + }, + ], + }, + ], }, { code: ` @@ -2345,12 +2519,17 @@ foo?.bar?.baz; endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const foo: { bar: { baz: { c: string } } } | null; foo?.bar.baz; `, + }, + ], + }, + ], }, { code: ` @@ -2364,12 +2543,17 @@ foo?.bar?.baz?.qux; endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const foo: { bar?: { baz: { qux: string } } } | null; foo?.bar?.baz.qux; `, + }, + ], + }, + ], }, { code: ` @@ -2383,6 +2567,15 @@ foo?.bar?.baz?.qux?.(); endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const foo: { bar: { baz: { qux?: () => {} } } } | null; +foo?.bar.baz?.qux?.(); + `, + }, + ], }, { column: 14, @@ -2390,12 +2583,17 @@ foo?.bar?.baz?.qux?.(); endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const foo: { bar: { baz: { qux?: () => {} } } } | null; -foo?.bar.baz.qux?.(); +foo?.bar?.baz.qux?.(); `, + }, + ], + }, + ], }, { code: ` @@ -2409,6 +2607,15 @@ foo?.bar?.baz?.qux?.(); endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const foo: { bar: { baz: { qux: () => {} } } } | null; +foo?.bar.baz?.qux?.(); + `, + }, + ], }, { column: 14, @@ -2416,6 +2623,15 @@ foo?.bar?.baz?.qux?.(); endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const foo: { bar: { baz: { qux: () => {} } } } | null; +foo?.bar?.baz.qux?.(); + `, + }, + ], }, { column: 19, @@ -2423,12 +2639,17 @@ foo?.bar?.baz?.qux?.(); endLine: 3, line: 3, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const foo: { bar: { baz: { qux: () => {} } } } | null; -foo?.bar.baz.qux(); +foo?.bar?.baz?.qux(); `, + }, + ], + }, + ], }, { code: ` @@ -2443,6 +2664,16 @@ foo?.bar?.baz?.().qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +type baz = () => { qux: () => {} }; +declare const foo: { bar: { baz: baz } } | null; +foo?.bar.baz?.().qux?.(); + `, + }, + ], }, { column: 14, @@ -2450,6 +2681,16 @@ foo?.bar?.baz?.().qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +type baz = () => { qux: () => {} }; +declare const foo: { bar: { baz: baz } } | null; +foo?.bar?.baz().qux?.(); + `, + }, + ], }, { column: 22, @@ -2457,13 +2698,18 @@ foo?.bar?.baz?.().qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type baz = () => { qux: () => {} }; declare const foo: { bar: { baz: baz } } | null; -foo?.bar.baz().qux(); +foo?.bar?.baz?.().qux(); `, + }, + ], + }, + ], }, { code: ` @@ -2478,6 +2724,16 @@ foo?.bar?.baz?.().qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +type baz = null | (() => { qux: () => {} }); +declare const foo: { bar: { baz: baz } } | null; +foo?.bar.baz?.().qux?.(); + `, + }, + ], }, { column: 22, @@ -2485,13 +2741,18 @@ foo?.bar?.baz?.().qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type baz = null | (() => { qux: () => {} }); declare const foo: { bar: { baz: baz } } | null; -foo?.bar.baz?.().qux(); +foo?.bar?.baz?.().qux(); `, + }, + ], + }, + ], }, { code: ` @@ -2506,6 +2767,16 @@ foo?.bar?.baz?.()?.qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +type baz = null | (() => { qux: () => {} } | null); +declare const foo: { bar: { baz: baz } } | null; +foo?.bar.baz?.()?.qux?.(); + `, + }, + ], }, { column: 23, @@ -2513,13 +2784,18 @@ foo?.bar?.baz?.()?.qux?.(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type baz = null | (() => { qux: () => {} } | null); declare const foo: { bar: { baz: baz } } | null; -foo?.bar.baz?.()?.qux(); +foo?.bar?.baz?.()?.qux(); `, + }, + ], + }, + ], }, { code: ` @@ -2535,25 +2811,41 @@ foo?.fooOrBar?.baz?.qux; endLine: 5, line: 5, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type Foo = { baz: number }; type Bar = { baz: null | string | { qux: string } }; declare const foo: { fooOrBar: Foo | Bar } | null; foo?.fooOrBar.baz?.qux; `, + }, + ], + }, + ], }, { code: ` declare const x: { a: { b: number } }[]; x[0].a?.b; `, - errors: [{ column: 7, line: 3, messageId: 'neverOptionalChain' }], - output: ` + errors: [ + { + column: 7, + line: 3, + messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` declare const x: { a: { b: number } }[]; x[0].a.b; `, + }, + ], + }, + ], }, { code: ` @@ -2571,9 +2863,10 @@ foo?.[key]?.trim(); endLine: 7, line: 7, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type Foo = { [key: string]: string; foo: 'foo'; bar: 'bar' } | null; type Key = 'bar' | 'foo'; declare const foo: Foo; @@ -2581,6 +2874,10 @@ declare const key: Key; foo?.[key].trim(); `, + }, + ], + }, + ], }, { code: ` @@ -2596,14 +2893,19 @@ foo?.[key]?.trim(); endLine: 5, line: 5, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type Foo = { [key: string]: string; foo: 'foo'; bar: 'bar' } | null; declare const foo: Foo; const key = 'bar'; foo?.[key].trim(); `, + }, + ], + }, + ], }, { code: ` @@ -2626,9 +2928,10 @@ export function test(outer: Outer): number | undefined { endLine: 11, line: 11, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` interface Outer { inner?: { [key: string]: string | undefined; @@ -2641,6 +2944,10 @@ export function test(outer: Outer): number | undefined { return outer.inner?.[key].charCodeAt(0); } `, + }, + ], + }, + ], }, { code: ` @@ -2663,9 +2970,10 @@ function Foo(outer: Outer, key: Bar): number | undefined { endLine: 11, line: 11, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` interface Outer { inner?: { [key: string]: string | undefined; @@ -2678,6 +2986,10 @@ function Foo(outer: Outer, key: Bar): number | undefined { return outer.inner?.[key].charCodeAt(0); } `, + }, + ], + }, + ], }, // https://github.com/typescript-eslint/typescript-eslint/issues/2384 { @@ -2769,9 +3081,10 @@ foo?.test?.length; endLine: 9, line: 9, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` interface Foo { test: string; [key: string]: [string] | undefined; @@ -2781,6 +3094,10 @@ type OptionalFoo = Foo | undefined; declare const foo: OptionalFoo; foo?.test.length; `, + }, + ], + }, + ], }, { code: ` @@ -2961,13 +3278,18 @@ foo?.bar()?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` type Foo = { bar: () => number } | null; declare const foo: Foo; foo?.bar().toExponential(); `, + }, + ], + }, + ], }, { code: ` @@ -2982,6 +3304,16 @@ foo?.bar?.baz()?.qux?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` +type Foo = { bar: null | { baz: () => { qux: number } } } | null; +declare const foo: Foo; +foo?.bar?.baz().qux?.toExponential(); + `, + }, + ], }, { column: 21, @@ -2989,13 +3321,18 @@ foo?.bar?.baz()?.qux?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` type Foo = { bar: null | { baz: () => { qux: number } } } | null; declare const foo: Foo; -foo?.bar?.baz().qux.toExponential(); +foo?.bar?.baz()?.qux.toExponential(); `, + }, + ], + }, + ], }, { code: ` @@ -3010,13 +3347,18 @@ foo?.()?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` type Foo = (() => number) | null; declare const foo: Foo; foo?.().toExponential(); `, + }, + ], + }, + ], }, { code: ` @@ -3031,13 +3373,18 @@ foo?.['bar']()?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` type Foo = { [key: string]: () => number } | null; declare const foo: Foo; foo?.['bar']().toExponential(); `, + }, + ], + }, + ], }, { code: ` @@ -3052,13 +3399,18 @@ foo?.['bar']?.()?.toExponential(); endLine: 4, line: 4, messageId: 'neverOptionalChain', - }, - ], - output: noFormat` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: noFormat` type Foo = { [key: string]: () => number } | null; declare const foo: Foo; foo?.['bar']?.().toExponential(); `, + }, + ], + }, + ], }, { code: ` @@ -3219,9 +3571,10 @@ a.a?.a?.a; endLine: 12, line: 12, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` type A = { [name in Lowercase]?: { [name in Lowercase]: { @@ -3234,6 +3587,10 @@ declare const a: A; a.a?.a.a; `, + }, + ], + }, + ], }, { code: ` @@ -3265,6 +3622,33 @@ t.a?.a?.a?.value; endLine: 21, line: 21, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +interface T { + [name: Lowercase]: { + [name: Lowercase]: { + [name: Lowercase]: { + value: 'value'; + }; + }; + }; + [name: Uppercase]: null | { + [name: Uppercase]: null | { + [name: Uppercase]: null | { + VALUE: 'VALUE'; + }; + }; + }; +} + +declare const t: T; + +t.a.a?.a?.value; + `, + }, + ], }, { column: 7, @@ -3272,6 +3656,33 @@ t.a?.a?.a?.value; endLine: 21, line: 21, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +interface T { + [name: Lowercase]: { + [name: Lowercase]: { + [name: Lowercase]: { + value: 'value'; + }; + }; + }; + [name: Uppercase]: null | { + [name: Uppercase]: null | { + [name: Uppercase]: null | { + VALUE: 'VALUE'; + }; + }; + }; +} + +declare const t: T; + +t.a?.a.a?.value; + `, + }, + ], }, { column: 10, @@ -3279,9 +3690,10 @@ t.a?.a?.a?.value; endLine: 21, line: 21, messageId: 'neverOptionalChain', - }, - ], - output: ` + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` interface T { [name: Lowercase]: { [name: Lowercase]: { @@ -3301,8 +3713,12 @@ interface T { declare const t: T; -t.a.a.a.value; +t.a?.a?.a.value; `, + }, + ], + }, + ], }, { code: ` @@ -3319,6 +3735,18 @@ if (test[0]?.a) { endLine: 5, line: 5, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const test: Array<{ a?: string }>; + +if (test[0]?.a) { + test[0].a; +} + `, + }, + ], }, ], languageOptions: { @@ -3328,13 +3756,6 @@ if (test[0]?.a) { tsconfigRootDir: getFixturesRootDir(), }, }, - output: ` -declare const test: Array<{ a?: string }>; - -if (test[0]?.a) { - test[0].a; -} - `, }, { code: ` @@ -3348,6 +3769,15 @@ arr2[42]?.x?.y?.z; endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const arr2: Array<{ x: { y: { z: object } } }>; +arr2[42]?.x.y?.z; + `, + }, + ], }, { column: 15, @@ -3355,6 +3785,15 @@ arr2[42]?.x?.y?.z; endLine: 3, line: 3, messageId: 'neverOptionalChain', + suggestions: [ + { + messageId: 'suggestRemoveOptionalChain', + output: ` +declare const arr2: Array<{ x: { y: { z: object } } }>; +arr2[42]?.x?.y.z; + `, + }, + ], }, ], languageOptions: { @@ -3364,10 +3803,6 @@ arr2[42]?.x?.y?.z; tsconfigRootDir: getFixturesRootDir(), }, }, - output: ` -declare const arr2: Array<{ x: { y: { z: object } } }>; -arr2[42]?.x.y.z; - `, }, { code: ` From 3fe4d7c1689c9b10b648b002d2f6042970479ce9 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Date: Wed, 16 Apr 2025 11:26:12 -0600 Subject: [PATCH 2/2] feedback --- packages/eslint-plugin/src/rules/no-unnecessary-condition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index f23495cb8b3f..9cad9dc413c2 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -185,7 +185,7 @@ export default createRule({ 'Unnecessary conditional, the types have no overlap.', noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.', - suggestRemoveOptionalChain: 'Replace `?.` with `.`', + suggestRemoveOptionalChain: 'Remove unnecessary optional chain', typeGuardAlreadyIsType: 'Unnecessary conditional, expression already has the type being checked by the {{typeGuardOrAssertionFunction}}.', }, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy