From b5aae54b5fafa4656c532a3fa1768e947b535328 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sun, 2 Jun 2024 15:29:14 +0900 Subject: [PATCH 1/7] remove no-useless-template-literals rule --- .../src/configs/disable-type-checked.ts | 1 - packages/eslint-plugin/src/rules/index.ts | 2 - .../src/rules/no-useless-template-literals.ts | 176 ----- .../no-useless-template-literals.test.ts | 646 ------------------ .../no-useless-template-literals.shot | 14 - .../src/configs/disable-type-checked.ts | 1 - 6 files changed, 840 deletions(-) delete mode 100644 packages/eslint-plugin/src/rules/no-useless-template-literals.ts delete mode 100644 packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts delete mode 100644 packages/eslint-plugin/tests/schema-snapshots/no-useless-template-literals.shot diff --git a/packages/eslint-plugin/src/configs/disable-type-checked.ts b/packages/eslint-plugin/src/configs/disable-type-checked.ts index 8cfdc2efbb76..3f4e1df77cfa 100644 --- a/packages/eslint-plugin/src/configs/disable-type-checked.ts +++ b/packages/eslint-plugin/src/configs/disable-type-checked.ts @@ -39,7 +39,6 @@ export = { '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/no-unsafe-unary-minus': 'off', '@typescript-eslint/no-useless-template-expression': 'off', - '@typescript-eslint/no-useless-template-literals': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', '@typescript-eslint/only-throw-error': 'off', '@typescript-eslint/prefer-destructuring': 'off', diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 56cf3a74959d..ab21477b3dba 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -85,7 +85,6 @@ import noUseBeforeDefine from './no-use-before-define'; import noUselessConstructor from './no-useless-constructor'; import noUselessEmptyExport from './no-useless-empty-export'; import noUselessTemplateExpression from './no-useless-template-expression'; -import noUselessTemplateLiterals from './no-useless-template-literals'; import noVarRequires from './no-var-requires'; import nonNullableTypeAssertionStyle from './non-nullable-type-assertion-style'; import onlyThrowError from './only-throw-error'; @@ -210,7 +209,6 @@ export default { 'no-useless-constructor': noUselessConstructor, 'no-useless-empty-export': noUselessEmptyExport, 'no-useless-template-expression': noUselessTemplateExpression, - 'no-useless-template-literals': noUselessTemplateLiterals, 'no-var-requires': noVarRequires, 'non-nullable-type-assertion-style': nonNullableTypeAssertionStyle, 'only-throw-error': onlyThrowError, diff --git a/packages/eslint-plugin/src/rules/no-useless-template-literals.ts b/packages/eslint-plugin/src/rules/no-useless-template-literals.ts deleted file mode 100644 index 43472c0141eb..000000000000 --- a/packages/eslint-plugin/src/rules/no-useless-template-literals.ts +++ /dev/null @@ -1,176 +0,0 @@ -import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import * as ts from 'typescript'; - -import { - createRule, - getConstrainedTypeAtLocation, - getParserServices, - getStaticStringValue, - isTypeFlagSet, - isUndefinedIdentifier, -} from '../util'; - -type MessageId = 'noUselessTemplateExpression'; - -export default createRule<[], MessageId>({ - name: 'no-useless-template-literals', - meta: { - fixable: 'code', - type: 'suggestion', - docs: { - description: 'Disallow unnecessary template literals', - requiresTypeChecking: true, - }, - messages: { - noUselessTemplateExpression: - 'Template literal expression is unnecessary and can be simplified.', - }, - schema: [], - deprecated: true, - replacedBy: ['@typescript-eslint/no-useless-template-expression'], - }, - defaultOptions: [], - create(context) { - const services = getParserServices(context); - - function isUnderlyingTypeString( - expression: TSESTree.Expression, - ): expression is TSESTree.StringLiteral | TSESTree.Identifier { - const type = getConstrainedTypeAtLocation(services, expression); - - const isString = (t: ts.Type): boolean => { - return isTypeFlagSet(t, ts.TypeFlags.StringLike); - }; - - if (type.isUnion()) { - return type.types.every(isString); - } - - if (type.isIntersection()) { - return type.types.some(isString); - } - - return isString(type); - } - - function isLiteral(expression: TSESTree.Expression): boolean { - return expression.type === AST_NODE_TYPES.Literal; - } - - function isTemplateLiteral(expression: TSESTree.Expression): boolean { - return expression.type === AST_NODE_TYPES.TemplateLiteral; - } - - function isInfinityIdentifier(expression: TSESTree.Expression): boolean { - return ( - expression.type === AST_NODE_TYPES.Identifier && - expression.name === 'Infinity' - ); - } - - function isNaNIdentifier(expression: TSESTree.Expression): boolean { - return ( - expression.type === AST_NODE_TYPES.Identifier && - expression.name === 'NaN' - ); - } - - return { - TemplateLiteral(node: TSESTree.TemplateLiteral): void { - if (node.parent.type === AST_NODE_TYPES.TaggedTemplateExpression) { - return; - } - - const hasSingleStringVariable = - node.quasis.length === 2 && - node.quasis[0].value.raw === '' && - node.quasis[1].value.raw === '' && - node.expressions.length === 1 && - isUnderlyingTypeString(node.expressions[0]); - - if (hasSingleStringVariable) { - context.report({ - node: node.expressions[0], - messageId: 'noUselessTemplateExpression', - 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, - ]), - ]; - }, - }); - - return; - } - - const fixableExpressions = node.expressions.filter( - expression => - isLiteral(expression) || - isTemplateLiteral(expression) || - isUndefinedIdentifier(expression) || - isInfinityIdentifier(expression) || - isNaNIdentifier(expression), - ); - - fixableExpressions.forEach(expression => { - context.report({ - node: expression, - messageId: 'noUselessTemplateExpression', - fix(fixer): TSESLint.RuleFix[] { - const index = node.expressions.indexOf(expression); - const prevQuasi = node.quasis[index]; - const nextQuasi = node.quasis[index + 1]; - - // Remove the quasis' parts that are related to the current expression. - const fixes = [ - fixer.removeRange([ - prevQuasi.range[1] - 2, - expression.range[0], - ]), - - fixer.removeRange([ - expression.range[1], - nextQuasi.range[0] + 1, - ]), - ]; - - const stringValue = getStaticStringValue(expression); - - if (stringValue != null) { - const escapedValue = stringValue.replace(/([`$\\])/g, '\\$1'); - - fixes.push(fixer.replaceText(expression, escapedValue)); - } else if (isTemplateLiteral(expression)) { - // 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 deleted file mode 100644 index 4c02f042b986..000000000000 --- a/packages/eslint-plugin/tests/rules/no-useless-template-literals.test.ts +++ /dev/null @@ -1,646 +0,0 @@ -import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; - -import rule from '../../src/rules/no-useless-template-literals'; -import { getFixturesRootDir } from '../RuleTester'; - -const rootPath = getFixturesRootDir(); - -const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: rootPath, - project: './tsconfig.json', - }, -}); - -ruleTester.run('no-useless-template-literals', rule, { - valid: [ - "const string = 'a';", - 'const string = `a`;', - ` - declare const string: 'a'; - \`\${string}b\`; - `, - - ` - declare const number: 1; - \`\${number}b\`; - `, - - ` - declare const boolean: true; - \`\${boolean}b\`; - `, - - ` - declare const nullish: null; - \`\${nullish}-undefined\`; - `, - - ` - declare const undefinedish: undefined; - \`\${undefinedish}\`; - `, - - ` - declare const left: 'a'; - declare const right: 'b'; - \`\${left}\${right}\`; - `, - - ` - declare const left: 'a'; - declare const right: 'c'; - \`\${left}b\${right}\`; - `, - - ` - declare const left: 'a'; - declare const center: 'b'; - declare const right: 'c'; - \`\${left}\${center}\${right}\`; - `, - - '`1 + 1 = ${1 + 1}`;', - - '`true && false = ${true && false}`;', - - "tag`${'a'}${'b'}`;", - - '`${function () {}}`;', - - '`${() => {}}`;', - - '`${(...args: any[]) => args}`;', - - ` - declare const number: 1; - \`\${number}\`; - `, - - ` - declare const boolean: true; - \`\${boolean}\`; - `, - - ` - declare const nullish: null; - \`\${nullish}\`; - `, - - ` - declare const union: string | number; - \`\${union}\`; - `, - - ` - declare const unknown: unknown; - \`\${unknown}\`; - `, - - ` - declare const never: never; - \`\${never}\`; - `, - - ` - declare const any: any; - \`\${any}\`; - `, - - ` - function func(arg: T) { - \`\${arg}\`; - } - `, - - ` - \`with - - new line\`; - `, - - ` - declare const a: 'a'; - - \`\${a} with - - new line\`; - `, - - noFormat` - \`with windows \r new line\`; - `, - - ` -\`not a useless \${String.raw\`nested interpolation \${a}\`}\`; - `, - ], - - invalid: [ - { - code: '`${1}`;', - output: '`1`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 5, - }, - ], - }, - { - code: '`${1n}`;', - output: '`1`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 6, - }, - ], - }, - { - code: '`${/a/}`;', - output: '`/a/`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 7, - }, - ], - }, - - { - code: noFormat`\`\${ 1 }\`;`, - output: '`1`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: noFormat`\`\${ 'a' }\`;`, - output: `'a';`, - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: noFormat`\`\${ "a" }\`;`, - output: `"a";`, - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: noFormat`\`\${ 'a' + 'b' }\`;`, - output: `'a' + 'b';`, - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: '`${true}`;', - output: '`true`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 8, - }, - ], - }, - - { - code: noFormat`\`\${ true }\`;`, - output: '`true`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: '`${null}`;', - output: '`null`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 8, - }, - ], - }, - - { - code: noFormat`\`\${ null }\`;`, - output: '`null`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: '`${undefined}`;', - output: '`undefined`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 13, - }, - ], - }, - - { - code: noFormat`\`\${ undefined }\`;`, - output: '`undefined`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: '`${Infinity}`;', - output: '`Infinity`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 12, - }, - ], - }, - - { - code: '`${NaN}`;', - output: '`NaN`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 7, - }, - ], - }, - - { - code: "`${'a'} ${'b'}`;", - output: '`a b`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 7, - }, - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 11, - endColumn: 14, - }, - ], - }, - - { - code: noFormat`\`\${ 'a' } \${ 'b' }\`;`, - output: '`a b`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: ` - declare const b: 'b'; - \`a\${b}\${'c'}\`; - `, - output: ` - declare const b: 'b'; - \`a\${b}c\`; - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 3, - column: 17, - endColumn: 20, - }, - ], - }, - - { - code: "`use${'less'}`;", - output: '`useless`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - }, - ], - }, - - { - code: '`use${`less`}`;', - output: '`useless`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - 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: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: noFormat` -\`u\${ - // hopefully this comment is not needed. - 'se' - -}\${ - \`le\${ \`ss\` }\` -}\`; - `, - output: [ - ` -\`use\${ - \`less\` -}\`; - `, - ` -\`useless\`; - `, - ], - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 4, - }, - { - messageId: 'noUselessTemplateExpression', - line: 7, - column: 3, - endLine: 7, - }, - { - messageId: 'noUselessTemplateExpression', - line: 7, - column: 10, - endLine: 7, - }, - ], - }, - { - code: noFormat` -\`use\${ - \`less\` -}\`; - `, - output: ` -\`useless\`; - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 3, - column: 3, - endColumn: 9, - }, - ], - }, - - { - code: "`${'1 + 1 ='} ${2}`;", - output: '`1 + 1 = 2`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 13, - }, - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 17, - endColumn: 18, - }, - ], - }, - - { - code: "`${'a'} ${true}`;", - output: '`a true`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 7, - }, - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 11, - endColumn: 15, - }, - ], - }, - - { - code: ` - declare const string: 'a'; - \`\${string}\`; - `, - output: ` - declare const string: 'a'; - string; - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 3, - column: 12, - endColumn: 18, - }, - ], - }, - - { - code: noFormat` - declare const string: 'a'; - \`\${ string }\`; - `, - output: ` - declare const string: 'a'; - string; - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: "`${String(Symbol.for('test'))}`;", - output: "String(Symbol.for('test'));", - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 1, - column: 4, - endColumn: 30, - }, - ], - }, - - { - code: ` - declare const intersection: string & { _brand: 'test-brand' }; - \`\${intersection}\`; - `, - output: ` - declare const intersection: string & { _brand: 'test-brand' }; - intersection; - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 3, - column: 12, - endColumn: 24, - }, - ], - }, - - { - code: ` - function func(arg: T) { - \`\${arg}\`; - } - `, - output: ` - function func(arg: T) { - arg; - } - `, - errors: [ - { - messageId: 'noUselessTemplateExpression', - line: 3, - column: 14, - endColumn: 17, - }, - ], - }, - - { - code: "`${'`'}`;", - output: "'`';", - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: "`back${'`'}tick`;", - output: '`back\\`tick`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: "`dollar${'${`this is test`}'}sign`;", - output: '`dollar\\${\\`this is test\\`}sign`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: '`complex${\'`${"`${test}`"}`\'}case`;', - output: '`complex\\`\\${"\\`\\${test}\\`"}\\`case`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: "`some ${'\\\\${test}'} string`;", - output: '`some \\\\\\${test} string`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - - { - code: "`some ${'\\\\`'} string`;", - output: '`some \\\\\\` string`;', - errors: [ - { - messageId: 'noUselessTemplateExpression', - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin/tests/schema-snapshots/no-useless-template-literals.shot b/packages/eslint-plugin/tests/schema-snapshots/no-useless-template-literals.shot deleted file mode 100644 index 785d465a8408..000000000000 --- a/packages/eslint-plugin/tests/schema-snapshots/no-useless-template-literals.shot +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Rule schemas should be convertible to TS types for documentation purposes no-useless-template-literals 1`] = ` -" -# SCHEMA: - -[] - - -# TYPES: - -/** No options declared */ -type Options = [];" -`; diff --git a/packages/typescript-eslint/src/configs/disable-type-checked.ts b/packages/typescript-eslint/src/configs/disable-type-checked.ts index 271a8d4d6da3..acd5ac59de90 100644 --- a/packages/typescript-eslint/src/configs/disable-type-checked.ts +++ b/packages/typescript-eslint/src/configs/disable-type-checked.ts @@ -42,7 +42,6 @@ export default ( '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/no-unsafe-unary-minus': 'off', '@typescript-eslint/no-useless-template-expression': 'off', - '@typescript-eslint/no-useless-template-literals': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', '@typescript-eslint/only-throw-error': 'off', '@typescript-eslint/prefer-destructuring': 'off', From 87d2982899a5c8b41fe9612c1e8ed22638550ec0 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sun, 2 Jun 2024 15:29:35 +0900 Subject: [PATCH 2/7] fix no-useless-template-literals docs --- .../rules/no-useless-template-expression.mdx | 9 ---- .../rules/no-useless-template-literals.mdx | 23 ---------- .../no-useless-template-literals.shot | 46 ------------------- 3 files changed, 78 deletions(-) delete mode 100644 packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx delete mode 100644 packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-useless-template-literals.shot diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx index 2b6a28802b22..103efb1500fd 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx +++ b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx @@ -11,15 +11,6 @@ import TabItem from '@theme/TabItem'; This rule reports template literals that contain substitution expressions (also variously referred to as embedded expressions or string interpolations) that are unnecessary and can be simplified. -:::info[Migration from `no-useless-template-literals`] - -This rule was formerly known as [`no-useless-template-literals`](./no-useless-template-literals.mdx). -We encourage users to migrate to the new name, `no-useless-template-expression`, as the old name will be removed in a future major version of typescript-eslint. - -The new name is a drop-in replacement with identical functionality. - -::: - ## Examples diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx deleted file mode 100644 index 72f66be8b876..000000000000 --- a/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -description: 'Disallow unnecessary template literals.' ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -> 🛑 This file is source code, not the primary documentation location! 🛑 -> -> See **https://typescript-eslint.io/rules/no-useless-template-literals** for documentation. - -This rule reports template literals that contain substitution expressions (also variously referred to as embedded expressions or string interpolations) that are unnecessary and can be simplified. - -:::warning -This rule is being renamed to [`no-useless-template-expression`](./no-useless-template-expression.mdx). -The current name, `no-useless-template-literals`, will be removed in a future major version of typescript-eslint. - -After the creation of this rule, it was realized that the name `no-useless-template-literals` could be misleading, seeing as this rule only targets template literals with substitution expressions. -In particular, it does _not_ aim to flag useless template literals that look like `` `this` `` and could be simplified to `"this"`. -If you are looking for such a rule, you can configure the [`@stylistic/ts/quotes`](https://eslint.style/rules/ts/quotes) rule to do this. -::: - -{/* Intentionally Omitted: When Not To Use It */} diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-useless-template-literals.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-useless-template-literals.shot deleted file mode 100644 index 3cc841703a98..000000000000 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-useless-template-literals.shot +++ /dev/null @@ -1,46 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Validating rule docs no-useless-template-literals.mdx code examples ESLint output 1`] = ` -"Incorrect - -const ab1 = \`\${'a'}\${'b'}\`; - ~~~ Template literal expression is unnecessary and can be simplified. - ~~~ Template literal expression is unnecessary and can be simplified. -const ab2 = \`a\${'b'}\`; - ~~~ Template literal expression is unnecessary and can be simplified. - -const stringWithNumber = \`\${'1 + 1 = '}\${2}\`; - ~~~~~~~~~~ Template literal expression is unnecessary and can be simplified. - ~ Template literal expression is unnecessary and can be simplified. - -const stringWithBoolean = \`\${'true is '}\${true}\`; - ~~~~~~~~~~ Template literal expression is unnecessary and can be simplified. - ~~~~ Template literal expression is unnecessary and can be simplified. - -const text = 'a'; -const wrappedText = \`\${text}\`; - ~~~~ Template literal expression is unnecessary and can be simplified. - -declare const intersectionWithString: string & { _brand: 'test-brand' }; -const wrappedIntersection = \`\${intersectionWithString}\`; - ~~~~~~~~~~~~~~~~~~~~~~ Template literal expression is unnecessary and can be simplified. -" -`; - -exports[`Validating rule docs no-useless-template-literals.mdx code examples ESLint output 2`] = ` -"Correct - -const ab1 = 'ab'; -const ab2 = 'ab'; - -const stringWithNumber = \`1 + 1 = 2\`; - -const stringWithBoolean = \`true is true\`; - -const text = 'a'; -const wrappedText = text; - -declare const intersectionWithString: string & { _brand: 'test-brand' }; -const wrappedIntersection = intersectionWithString; -" -`; From af6322528d0b8191c27125ca7a0227549747b20f Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 3 Jun 2024 00:41:10 +0900 Subject: [PATCH 3/7] revert removal --- .../docs/rules/no-useless-template-expression.mdx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx index 103efb1500fd..2b6a28802b22 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx +++ b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx @@ -11,6 +11,15 @@ import TabItem from '@theme/TabItem'; This rule reports template literals that contain substitution expressions (also variously referred to as embedded expressions or string interpolations) that are unnecessary and can be simplified. +:::info[Migration from `no-useless-template-literals`] + +This rule was formerly known as [`no-useless-template-literals`](./no-useless-template-literals.mdx). +We encourage users to migrate to the new name, `no-useless-template-expression`, as the old name will be removed in a future major version of typescript-eslint. + +The new name is a drop-in replacement with identical functionality. + +::: + ## Examples From 9401d15e1b991dd646f6992b038e731a8ca4ab62 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 3 Jun 2024 00:50:51 +0900 Subject: [PATCH 4/7] keep as tombstone page --- .../docs/rules/no-useless-template-literals.mdx | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx new file mode 100644 index 000000000000..1d59577d5527 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx @@ -0,0 +1,5 @@ +:::danger Deprecated + +This rule has been renamed to [`no-useless-template-expression`](./no-useless-template-expression.mdx). See [#8544](https://github.com/typescript-eslint/typescript-eslint/issues/8544) for more information. + +::: From c7a4ba5c069c88231be4e84638a472d78d12ac66 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 3 Jun 2024 11:00:31 +0900 Subject: [PATCH 5/7] fix doc --- .../eslint-plugin/docs/rules/no-useless-template-expression.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx index 2b6a28802b22..c35ec7aba3c3 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx +++ b/packages/eslint-plugin/docs/rules/no-useless-template-expression.mdx @@ -14,8 +14,6 @@ This rule reports template literals that contain substitution expressions (also :::info[Migration from `no-useless-template-literals`] This rule was formerly known as [`no-useless-template-literals`](./no-useless-template-literals.mdx). -We encourage users to migrate to the new name, `no-useless-template-expression`, as the old name will be removed in a future major version of typescript-eslint. - The new name is a drop-in replacement with identical functionality. ::: From 8cfc4092a2b9a7a0b770656d1efaad5f6064ee5f Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 3 Jun 2024 12:26:49 +0900 Subject: [PATCH 6/7] fix docs test --- packages/eslint-plugin/tests/docs.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index e71524a0beac..53d0838af93e 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -157,6 +157,7 @@ describe('Validating rule docs', () => { // comments in the files for more information. 'no-duplicate-imports.mdx', 'no-parameter-properties.mdx', + 'no-useless-template-literals.mdx', ...oldStylisticRules, ]); From 2936bd5070c2f93df093c7d235a7f15f391d04cc Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 3 Jun 2024 12:44:20 +0900 Subject: [PATCH 7/7] fix doc --- .../eslint-plugin/docs/rules/no-useless-template-literals.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx b/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx index 1d59577d5527..812db678b319 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx +++ b/packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx @@ -1,5 +1,5 @@ :::danger Deprecated -This rule has been renamed to [`no-useless-template-expression`](./no-useless-template-expression.mdx). See [#8544](https://github.com/typescript-eslint/typescript-eslint/issues/8544) for more information. +This rule has been renamed to [`no-unnecessary-template-expression`](./no-unnecessary-template-expression.mdx). See [#8544](https://github.com/typescript-eslint/typescript-eslint/issues/8544) for more information. :::