diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index b05e43d0431..8f4cffd98ff 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -18,7 +18,11 @@ import { nullThrows, NullThrowsReasons, skipChainExpression, + isParenthesized, + getOperatorPrecedenceForNode, + OperatorPrecedence, } from '../util'; +import { getWrappedCode } from '../util/getWrappedCode'; const isMemberAccessLike = isNodeOfTypes([ AST_NODE_TYPES.ChainExpression, @@ -489,9 +493,14 @@ export default createRule({ return; } + const { nonNullishBranch, nullishBranch } = getBranchNodes( + node, + operator, + ); + const nullishCoalescingParams = getNullishCoalescingParams( node, - getBranchNodes(node, operator).nonNullishBranch, + nonNullishBranch, nodesInsideTestExpression, operator, ); @@ -507,15 +516,27 @@ export default createRule({ messageId: 'suggestNullish', data: { equals: '' }, fix(fixer: TSESLint.RuleFixer): TSESLint.RuleFix { + const nullishBranchText = getTextWithParentheses( + context.sourceCode, + nullishBranch, + ); + const rightOperandReplacement = isParenthesized( + nullishBranch, + context.sourceCode, + ) + ? nullishBranchText + : getWrappedCode( + nullishBranchText, + getOperatorPrecedenceForNode(nullishBranch), + OperatorPrecedence.Coalesce, + ); + return fixer.replaceText( node, `${getTextWithParentheses( context.sourceCode, nullishCoalescingParams.nullishCoalescingLeftNode, - )} ?? ${getTextWithParentheses( - context.sourceCode, - getBranchNodes(node, operator).nullishBranch, - )}`, + )} ?? ${rightOperandReplacement}`, ); }, }, 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 0926a839ee3..618d1c24441 100644 --- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts @@ -6248,5 +6248,76 @@ function weirdParens() { ], output: null, }, + { + code: ` +let a: string | undefined; +let b: { message: string } | undefined; + +const foo = a ? a : b ? 1 : 2; + `, + errors: [ + { + messageId: 'preferNullishOverTernary', + suggestions: [ + { + messageId: 'suggestNullish', + output: ` +let a: string | undefined; +let b: { message: string } | undefined; + +const foo = a ?? (b ? 1 : 2); + `, + }, + ], + }, + ], + output: null, + }, + { + code: noFormat` +let a: string | undefined; +let b: { message: string } | undefined; + +const foo = a ? a : (b ? 1 : 2); + `, + errors: [ + { + messageId: 'preferNullishOverTernary', + suggestions: [ + { + messageId: 'suggestNullish', + output: ` +let a: string | undefined; +let b: { message: string } | undefined; + +const foo = a ?? (b ? 1 : 2); + `, + }, + ], + }, + ], + output: null, + }, + { + code: ` +declare const c: string | null; +c !== null ? c : c ? 1 : 2; + `, + errors: [ + { + messageId: 'preferNullishOverTernary', + suggestions: [ + { + messageId: 'suggestNullish', + output: ` +declare const c: string | null; +c ?? (c ? 1 : 2); + `, + }, + ], + }, + ], + output: null, + }, ], });