From 8bdddbd394bb12a8c02070add2e88f028ceec89f Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Mon, 4 Mar 2024 10:50:10 -0700 Subject: [PATCH] flag useless nested template literals --- .../src/rules/no-useless-template-literals.ts | 18 ++++- .../no-useless-template-literals.test.ts | 66 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-useless-template-literals.ts b/packages/eslint-plugin/src/rules/no-useless-template-literals.ts index e80216fd5cbf..727f7d8c270c 100644 --- a/packages/eslint-plugin/src/rules/no-useless-template-literals.ts +++ b/packages/eslint-plugin/src/rules/no-useless-template-literals.ts @@ -110,11 +110,12 @@ export default createRule<[], MessageId>({ } const fixableExpressions = node.expressions.filter( - (expression): expression is TSESTree.Literal | TSESTree.Identifier => + expression => isLiteral(expression) || isUndefinedIdentifier(expression) || isInfinityIdentifier(expression) || - isNaNIdentifier(expression), + isNaNIdentifier(expression) || + expression.type === AST_NODE_TYPES.TemplateLiteral, ); fixableExpressions.forEach(expression => { @@ -145,6 +146,19 @@ export default createRule<[], MessageId>({ const escapedValue = stringValue.replace(/([`$\\])/g, '\\$1'); fixes.push(fixer.replaceText(expression, escapedValue)); + } else if (expression.type === AST_NODE_TYPES.TemplateLiteral) { + // Note that some template literals get handled in the previous branch too. + // Remove the beginning and trailing backtick characters. + fixes.push( + fixer.removeRange([ + expression.range[0], + expression.range[0] + 1, + ]), + fixer.removeRange([ + expression.range[1] - 1, + expression.range[1], + ]), + ); } return fixes; diff --git a/packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts b/packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts index 0653e2506505..4dbe33006b94 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts @@ -131,6 +131,10 @@ ruleTester.run('no-useless-template-literals', rule, { noFormat` \`with windows \r new line\`; `, + + ` +\`not a useless \${String.raw\`nested interpolation \${a}\`}\`; + `, ], invalid: [ @@ -555,5 +559,67 @@ ruleTester.run('no-useless-template-literals', rule, { }, ], }, + + { + code: "`use${'less'}`;", + output: '`useless`;', + errors: [ + { + messageId: 'noUselessTemplateLiteral', + line: 1, + }, + ], + }, + + { + code: ` +declare const nested: string, interpolation: string; +\`use\${\`less\${nested}\${interpolation}\`}\`; + `, + output: ` +declare const nested: string, interpolation: string; +\`useless\${nested}\${interpolation}\`; + `, + errors: [ + { + messageId: 'noUselessTemplateLiteral', + }, + ], + }, + + { + code: noFormat` +\`u\${ + // hopefully this comment is not needed. + 'se' + +}\${ + \`le\${ \`ss\` }\` +}\`; + `, + output: ` +\`use\${ + \`less\` +}\`; + `, + errors: [ + { + messageId: 'noUselessTemplateLiteral', + line: 4, + }, + { + messageId: 'noUselessTemplateLiteral', + line: 7, + column: 3, + endLine: 7, + }, + { + messageId: 'noUselessTemplateLiteral', + line: 7, + column: 10, + endLine: 7, + }, + ], + }, ], });