From f0c1eff61651b4338b880b473fe0f451a1bf45b1 Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Fri, 18 Apr 2025 02:26:31 +0000 Subject: [PATCH] fix(linter): false positve in no-unused-vars (#10470) fixes #10458 --- .../rules/eslint/no_unused_vars/tests/oxc.rs | 24 +++++++++++++++++++ .../src/rules/eslint/no_unused_vars/usage.rs | 21 ++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/oxc.rs b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/oxc.rs index e6c0204ad3e38..06596a7d27a70 100644 --- a/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/oxc.rs +++ b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/oxc.rs @@ -1202,6 +1202,30 @@ fn test_type_references() { .test_and_snapshot(); } +#[test] +fn test_ts_in_assignment() { + let pass = vec![ + r"export const onClick = (value, key) => { + const obj: Record = {}; + (obj[key] as any) = value; + }", + r"export const onClick = (value, key) => { + const obj: Record = {}; + (obj[key] satisfies any) = value; + }", + r"export const onClick = (value, key) => { + const obj: Record = {}; + (obj[key]!) = value; + }", + ]; + let fail = vec![]; + + Tester::new(NoUnusedVars::NAME, NoUnusedVars::PLUGIN, pass, fail) + .intentionally_allow_no_fix_tests() + .with_snapshot_suffix("oxc-assignment-ts") + .test(); +} + // #[test] // fn test_template() { // let pass = vec![]; diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_vars/usage.rs b/crates/oxc_linter/src/rules/eslint/no_unused_vars/usage.rs index 403c8ed5d74ac..31ab1a609aaab 100644 --- a/crates/oxc_linter/src/rules/eslint/no_unused_vars/usage.rs +++ b/crates/oxc_linter/src/rules/eslint/no_unused_vars/usage.rs @@ -411,6 +411,27 @@ impl<'a> Symbol<'_, 'a> { return false; // we can short-circuit } } + AssignmentTarget::TSAsExpression(v) + if v.expression.is_member_expression() => + { + return false; + } + AssignmentTarget::TSSatisfiesExpression(v) + if v.expression.is_member_expression() => + { + return false; + } + AssignmentTarget::TSNonNullExpression(v) + if v.expression.is_member_expression() => + { + return false; + } + AssignmentTarget::TSTypeAssertion(v) + if v.expression.is_member_expression() => + { + return false; + } + // variable is being used to index another variable, this is // always a usage // todo: check self index?