From b7ad4ffba9fe37de0240f75e74e6a007402076d1 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Tue, 4 Feb 2025 20:59:05 +0900 Subject: [PATCH] fix(eslint-plugin): [no-unnecessary-template-expression] ignore enum and enum mebers --- .../no-unnecessary-template-expression.mdx | 1 + .../no-unnecessary-template-expression.ts | 20 +++-- .../no-unnecessary-template-expression.shot | 1 + ...no-unnecessary-template-expression.test.ts | 79 +++++++++++++------ 4 files changed, 65 insertions(+), 36 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-template-expression.mdx b/packages/eslint-plugin/docs/rules/no-unnecessary-template-expression.mdx index 9262d9fea9be..aded1f4b85a0 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-template-expression.mdx +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-template-expression.mdx @@ -66,6 +66,7 @@ enum ABC { C = 'C', } type ABCUnion = `${ABC}`; +type A = `${ABC.A}`; // Interpolating type parameters is allowed. type TextUtil = `${T}`; 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 842f549eb34a..6c70e134043e 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-template-expression.ts @@ -1,6 +1,7 @@ import type { TSESLint } from '@typescript-eslint/utils'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/utils'; +import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; import { @@ -76,16 +77,13 @@ export default createRule<[], MessageId>({ return isStringLike(type); } - /** - * Checks for whole enum types, i.e. `MyEnum`, and not their values, i.e. `MyEnum.A` - */ - function isEnumType(type: ts.Type): boolean { - const symbol = type.getSymbol(); - - return !!( - symbol?.valueDeclaration && - ts.isEnumDeclaration(symbol.valueDeclaration) - ); + function isEnumMemberType(type: ts.Type): boolean { + return tsutils.typeParts(type).some(t => { + const symbol = t.getSymbol(); + return !!( + symbol?.valueDeclaration && ts.isEnumMember(symbol.valueDeclaration) + ); + }); } const isLiteral = isNodeOfType(TSESTree.AST_NODE_TYPES.Literal); @@ -460,7 +458,7 @@ export default createRule<[], MessageId>({ constraintType && !isTypeParameter && isUnderlyingTypeString(constraintType) && - !isEnumType(constraintType) + !isEnumMemberType(constraintType) ) { reportSingleInterpolation(node); return; diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-unnecessary-template-expression.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-unnecessary-template-expression.shot index 2d5241b52e5e..b4662d8bdcfd 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-unnecessary-template-expression.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-unnecessary-template-expression.shot @@ -59,6 +59,7 @@ enum ABC { C = 'C', } type ABCUnion = \`\${ABC}\`; +type A = \`\${ABC.A}\`; // Interpolating type parameters is allowed. type TextUtil = \`\${T}\`; 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 f60f87126f78..191cfeeb0de7 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 @@ -1188,6 +1188,60 @@ enum Foo { A = 1, B = 2, } +type Bar = \`\${Foo.A}\`; + `, + ` +enum Enum1 { + A = 'A1', + B = 'B1', +} + +enum Enum2 { + A = 'A2', + B = 'B2', +} + +type Union = \`\${Enum1 | Enum2}\`; + `, + ` +enum Enum1 { + A = 'A1', + B = 'B1', +} + +enum Enum2 { + A = 'A2', + B = 'B2', +} + +type Union = \`\${Enum1.A | Enum2.B}\`; + `, + ` +enum Enum1 { + A = 'A1', + B = 'B1', +} + +enum Enum2 { + A = 'A2', + B = 'B2', +} +type Enums = Enum1 | Enum2; +type Union = \`\${Enums}\`; + `, + ` +enum Enum { + A = 'A', + B = 'A', +} + +type Intersection = \`\${Enum1.A & string}\`; + `, + ` +enum Foo { + A = 'A', + B = 'B', +} type Bar = \`\${Foo.A}\`; `, ` @@ -1412,30 +1466,5 @@ type Bar = Foo; ], output: "type FooBar = 'foo' | 'bar';", }, - { - code: ` -enum Foo { - A = 'A', - B = 'B', -} -type Bar = \`\${Foo.A}\`; - `, - errors: [ - { - column: 13, - endColumn: 21, - endLine: 6, - line: 6, - messageId: 'noUnnecessaryTemplateExpression', - }, - ], - output: ` -enum Foo { - A = 'A', - B = 'B', -} -type Bar = Foo.A; - `, - }, ], }); 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