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 5ae12f5a33d..9b8d2ba76f5 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -137,19 +137,24 @@ export default util.createRule({ TSNonNullExpression(node): void { if ( node.parent?.type === AST_NODE_TYPES.AssignmentExpression && - node.parent?.operator === '=' && - node.parent.left === node + node.parent.operator === '=' ) { - context.report({ - node, - messageId: 'contextuallyUnnecessary', - fix(fixer) { - return fixer.removeRange([ - node.expression.range[1], - node.range[1], - ]); - }, - }); + if (node.parent.left === node) { + context.report({ + node, + messageId: 'contextuallyUnnecessary', + fix(fixer) { + return fixer.removeRange([ + node.expression.range[1], + node.range[1], + ]); + }, + }); + } + // for all other = assignments we ignore non-null checks + // this is because non-null assertions can change the type-flow of the code + // so whilst they might be unnecessary for the assignment - they are necessary + // for following code return; } 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 65d0874dd3a..0f530622b9a 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 @@ -202,6 +202,12 @@ let a: { b?: string } | undefined; a!.b = ''; `, }, + ` +let value: number | undefined; +let values: number[] = []; + +value = values.pop()!; + `, ], invalid: [ @@ -477,14 +483,10 @@ y! = 0; output: ` let x: number | undefined; let y: number | undefined; -y = x; +y = x!; y = 0; `, errors: [ - { - messageId: 'contextuallyUnnecessary', - line: 4, - }, { messageId: 'contextuallyUnnecessary', line: 5,