From a0da01bbd94298a27a494d19dd98f858e23b334e Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 16 Aug 2025 23:26:52 +0900 Subject: [PATCH 1/8] fix: disable suggestion when non-null assertion is used as an assignee --- packages/eslint-plugin/src/rules/no-non-null-assertion.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index fd66c1cef9b0..bc7c9ecf226e 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -4,6 +4,7 @@ import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import { createRule, + isAssignee, isNonNullAssertionPunctuator, nullThrows, NullThrowsReasons, @@ -53,7 +54,8 @@ export default createRule<[], MessageIds>({ if ( node.parent.type === AST_NODE_TYPES.MemberExpression && - node.parent.object === node + node.parent.object === node && + !isAssignee(node.parent) ) { if (!node.parent.optional) { if (node.parent.computed) { From f0feb9e954e6589eecb02cf391db7479d2644dc9 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 16 Aug 2025 23:27:54 +0900 Subject: [PATCH 2/8] test: add tests --- .../tests/rules/no-non-null-assertion.test.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 98dde42f9943..6c0e5bc7a8db 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -387,5 +387,39 @@ x?. }, ], }, + { + code: noFormat` +document.querySelector("input")!.files = new FileList(); +`, + errors: [ + { + column: 1, + endColumn: 33, + line: 2, + messageId: 'noNonNull', + }, + ], + }, + { + code: noFormat` +hoge.files = document.querySelector("input")!.files +`, + errors: [ + { + column: 14, + endColumn: 46, + line: 2, + messageId: 'noNonNull', + suggestions: [ + { + messageId: 'suggestOptionalChain', + output: ` +hoge.files = document.querySelector("input")?.files +`, + }, + ], + }, + ], + }, ], }); From 9aaa5258e35403bd2f67544d6b2ffd6969792ff5 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 16 Aug 2025 23:45:38 +0900 Subject: [PATCH 3/8] chore: fix lint errors --- packages/eslint-plugin/src/rules/naming-convention.ts | 2 +- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 02b95a5948fc..253842228a4e 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -634,7 +634,7 @@ export default createRule({ TSEnumMember: { handler: (node: TSESTree.TSEnumMember, validator): void => { // Unknown reason, can't get the correct type - const id = node.id as TSESTree.Identifier | TSESTree.StringLiteral; + const id = node.id; const modifiers = new Set(); if (requiresQuoting(id, compilerOptions.target)) { diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 6c0e5bc7a8db..74828457790e 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -390,7 +390,7 @@ x?. { code: noFormat` document.querySelector("input")!.files = new FileList(); -`, + `, errors: [ { column: 1, @@ -403,7 +403,7 @@ document.querySelector("input")!.files = new FileList(); { code: noFormat` hoge.files = document.querySelector("input")!.files -`, + `, errors: [ { column: 14, From 32488239bb65d4dc205e59beab4660e9af8591dc Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Thu, 28 Aug 2025 11:18:40 +0900 Subject: [PATCH 4/8] test: remove noFormat --- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 74828457790e..8cb3f0069d96 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -388,7 +388,7 @@ x?. ], }, { - code: noFormat` + code: ` document.querySelector("input")!.files = new FileList(); `, errors: [ @@ -401,7 +401,7 @@ document.querySelector("input")!.files = new FileList(); ], }, { - code: noFormat` + code: ` hoge.files = document.querySelector("input")!.files `, errors: [ From dd0bcd10db2283667836a0d3745d71b940a1f8af Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Thu, 28 Aug 2025 16:26:46 +0900 Subject: [PATCH 5/8] test: fix test output --- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 8cb3f0069d96..d14e006176e8 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -415,7 +415,7 @@ hoge.files = document.querySelector("input")!.files messageId: 'suggestOptionalChain', output: ` hoge.files = document.querySelector("input")?.files -`, + `, }, ], }, From 2ae4c827bc093f5bd1dad8561759810103f16842 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Thu, 28 Aug 2025 17:06:54 +0900 Subject: [PATCH 6/8] chore: fix lint --- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index d14e006176e8..0ef907ab6e72 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -389,7 +389,7 @@ x?. }, { code: ` -document.querySelector("input")!.files = new FileList(); +document.querySelector('input')!.files = new FileList(); `, errors: [ { @@ -402,7 +402,7 @@ document.querySelector("input")!.files = new FileList(); }, { code: ` -hoge.files = document.querySelector("input")!.files +hoge.files = document.querySelector('input')!.files; `, errors: [ { From 0ad658a26268de2d2193ab131e9a8fd96b3bdf0a Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Thu, 28 Aug 2025 17:25:20 +0900 Subject: [PATCH 7/8] test: fix test output --- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 0ef907ab6e72..1d2defa415f8 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -414,7 +414,7 @@ hoge.files = document.querySelector('input')!.files; { messageId: 'suggestOptionalChain', output: ` -hoge.files = document.querySelector("input")?.files +hoge.files = document.querySelector('input')?.files `, }, ], From cf7965b1fcf4d7828cd1108644f387715c2b54b9 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Thu, 28 Aug 2025 17:27:15 +0900 Subject: [PATCH 8/8] test: fix test output --- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 1d2defa415f8..137effe702cc 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -414,7 +414,7 @@ hoge.files = document.querySelector('input')!.files; { messageId: 'suggestOptionalChain', output: ` -hoge.files = document.querySelector('input')?.files +hoge.files = document.querySelector('input')?.files; `, }, ],