diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts b/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts index fe648e3bd873..dc15a9bbcd06 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts @@ -5,6 +5,7 @@ import * as ts from 'typescript'; import { createRule, getConstrainedTypeAtLocation, + getMovedNodeCode, getParserServices, isTypeFlagSet, isUndefinedIdentifier, @@ -106,21 +107,14 @@ export default createRule<[], MessageId>({ context.report({ node: node.expressions[0], messageId: 'noUnnecessaryTemplateExpression', - fix(fixer): TSESLint.RuleFix[] { - const [prevQuasi, nextQuasi] = node.quasis; - - // Remove the quasis and backticks. - return [ - fixer.removeRange([ - prevQuasi.range[1] - 3, - node.expressions[0].range[0], - ]), - - fixer.removeRange([ - node.expressions[0].range[1], - nextQuasi.range[0] + 2, - ]), - ]; + fix(fixer): TSESLint.RuleFix | null { + const wrappingCode = getMovedNodeCode({ + sourceCode: context.sourceCode, + nodeToMove: node.expressions[0], + destinationNode: node, + }); + + return fixer.replaceText(node, wrappingCode); }, }); diff --git a/packages/eslint-plugin/src/util/getWrappingFixer.ts b/packages/eslint-plugin/src/util/getWrappingFixer.ts index e6e71168fc41..cb45f1cdfc3d 100644 --- a/packages/eslint-plugin/src/util/getWrappingFixer.ts +++ b/packages/eslint-plugin/src/util/getWrappingFixer.ts @@ -74,6 +74,33 @@ export function getWrappingFixer( return fixer.replaceText(node, code); }; } +/** + * If the node to be moved and the destination node require parentheses, include parentheses in the node to be moved. + * @param sourceCode Source code of current file + * @param nodeToMove Nodes that need to be moved + * @param destinationNode Final destination node with nodeToMove + * @returns If parentheses are required, code for the nodeToMove node is returned with parentheses at both ends of the code. + */ +export function getMovedNodeCode(params: { + sourceCode: Readonly; + nodeToMove: TSESTree.Node; + destinationNode: TSESTree.Node; +}): string { + const { sourceCode, nodeToMove: existingNode, destinationNode } = params; + const code = sourceCode.getText(existingNode); + if (isStrongPrecedenceNode(existingNode)) { + // Moved node never needs parens + return code; + } + + if (!isWeakPrecedenceParent(destinationNode)) { + // Destination would never needs parens, regardless what node moves there + return code; + } + + // Parens may be necessary + return `(${code})`; +} /** * Check if a node will always have the same precedence if it's parent changes. @@ -98,8 +125,10 @@ export function isStrongPrecedenceNode(innerNode: TSESTree.Node): boolean { * Check if a node's parent could have different precedence if the node changes. */ function isWeakPrecedenceParent(node: TSESTree.Node): boolean { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const parent = node.parent!; + const parent = node.parent; + if (!parent) { + return false; + } if ( parent.type === AST_NODE_TYPES.UpdateExpression || diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-template-expression.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-template-expression.test.ts index 1dd79982f50f..3902b404d9ec 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-template-expression.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-template-expression.test.ts @@ -1127,5 +1127,14 @@ declare const nested: string, interpolation: string; }, ], }, + { + code: "true ? `${'test' || ''}`.trim() : undefined;", + output: "true ? ('test' || '').trim() : undefined;", + errors: [ + { + messageId: 'noUnnecessaryTemplateExpression', + }, + ], + }, ], }); 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