diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index a73962b9acbd..c01b8f9edb73 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -108,23 +108,23 @@ export default createRule({ ); } - function isLiteralVariableDeclarationChangingTypeWithConst( - node: TSESTree.TSAsExpression | TSESTree.TSTypeAssertion, - ): boolean { - /** - * If the type assertion is on a template literal WITH expressions we - * should keep the `const` casting - * @see https://github.com/typescript-eslint/typescript-eslint/issues/8737 - */ - if (node.expression.type === AST_NODE_TYPES.TemplateLiteral) { - return node.expression.expressions.length === 0; - } - + function isImplicitlyNarrowedConstDeclaration({ + expression, + parent, + }: TSESTree.TSAsExpression | TSESTree.TSTypeAssertion): boolean { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const maybeDeclarationNode = node.parent.parent!; + const maybeDeclarationNode = parent.parent!; + const isTemplateLiteralWithExpressions = + expression.type === AST_NODE_TYPES.TemplateLiteral && + expression.expressions.length !== 0; return ( maybeDeclarationNode.type === AST_NODE_TYPES.VariableDeclaration && - maybeDeclarationNode.kind === 'const' + maybeDeclarationNode.kind === 'const' && + /** + * Even on `const` variable declarations, template literals with expressions can sometimes be widened without a type assertion. + * @see https://github.com/typescript-eslint/typescript-eslint/issues/8737 + */ + !isTemplateLiteralWithExpressions ); } @@ -267,7 +267,7 @@ export default createRule({ const typeIsUnchanged = isTypeUnchanged(uncastType, castType); const wouldSameTypeBeInferred = castType.isLiteral() - ? isLiteralVariableDeclarationChangingTypeWithConst(node) + ? isImplicitlyNarrowedConstDeclaration(node) : !isConstAssertion(node.typeAnnotation); if (typeIsUnchanged && wouldSameTypeBeInferred) { diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 17efb3ff0baf..1b60d0a4ba14 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -284,14 +284,15 @@ function bar(items: string[]) { }, // https://github.com/typescript-eslint/typescript-eslint/issues/8737 ` -const myString = 'foo'; +let myString = 'foo'; const templateLiteral = \`\${myString}-somethingElse\` as const; `, // https://github.com/typescript-eslint/typescript-eslint/issues/8737 ` -const myString = 'foo'; +let myString = 'foo'; const templateLiteral = \`\${myString}-somethingElse\`; `, + 'let a = `a` as const;', { code: ` declare const foo: {