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 58ef344bf515..ea17c721404b 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -1,5 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import { AST_NODE_TYPES } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -263,23 +263,38 @@ export default createRule({ messageId: 'unnecessaryAssertion', fix(fixer) { if (node.type === AST_NODE_TYPES.TSTypeAssertion) { + const openingAngleBracket = sourceCode.getTokenBefore( + node.typeAnnotation, + token => + token.type === AST_TOKEN_TYPES.Punctuator && + token.value === '<', + )!; const closingAngleBracket = sourceCode.getTokenAfter( node.typeAnnotation, - ); - return closingAngleBracket?.value === '>' - ? fixer.removeRange([ - node.range[0], - closingAngleBracket.range[1], - ]) - : null; + token => + token.type === AST_TOKEN_TYPES.Punctuator && + token.value === '>', + )!; + // < ( number ) > ( 3 + 5 ) + // ^---remove---^ + return fixer.removeRange([ + openingAngleBracket.range[0], + closingAngleBracket.range[1], + ]); } - return fixer.removeRange([ - node.expression.range[1] + - (node.expression.type === AST_NODE_TYPES.CallExpression - ? 0 - : 1), - node.range[1], - ]); + // `as` is always present in TSAsExpression + const asToken = sourceCode.getTokenAfter( + node.expression, + token => + token.type === AST_TOKEN_TYPES.Identifier && + token.value === 'as', + )!; + const tokenBeforeAs = sourceCode.getTokenBefore(asToken, { + includeComments: true, + })!; + // ( 3 + 5 ) as number + // ^--remove--^ + return fixer.removeRange([tokenBeforeAs.range[1], node.range[1]]); }, }); } 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 2c3cc3599e83..3eb36636a839 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 @@ -1,4 +1,4 @@ -import { RuleTester } from '@typescript-eslint/rule-tester'; +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import path from 'path'; import rule from '../../src/rules/no-unnecessary-type-assertion'; @@ -660,5 +660,160 @@ const item = arr[0]; }, ], }, + { + code: noFormat` +const foo = ( 3 + 5 ) as number; + `, + output: ` +const foo = ( 3 + 5 ); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = ( 3 + 5 ) /*as*/ as number; + `, + output: ` +const foo = ( 3 + 5 ) /*as*/; + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = ( 3 + 5 + ) /*as*/ as //as + ( + number + ); + `, + output: ` +const foo = ( 3 + 5 + ) /*as*/; + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = (3 + (5 as number) ) as number; + `, + output: ` +const foo = (3 + (5 as number) ); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = 3 + 5/*as*/ as number; + `, + output: ` +const foo = 3 + 5/*as*/; + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = 3 + 5/*a*/ /*b*/ as number; + `, + output: ` +const foo = 3 + 5/*a*/ /*b*/; + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = <(number)>(3 + 5); + `, + output: ` +const foo = (3 + 5); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = < ( number ) >( 3 + 5 ); + `, + output: ` +const foo = ( 3 + 5 ); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = /* a */ (3 + 5); + `, + output: ` +const foo = /* a */ (3 + 5); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, + { + code: noFormat` +const foo = (3 + 5); + `, + output: ` +const foo = (3 + 5); + `, + errors: [ + { + messageId: 'unnecessaryAssertion', + line: 2, + column: 13, + }, + ], + }, ], });