diff --git a/crates/rome_js_analyze/src/semantic_analyzers/js/no_unused_variables.rs b/crates/rome_js_analyze/src/semantic_analyzers/js/no_unused_variables.rs index 4dc02a0957d..49282eedec2 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/js/no_unused_variables.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/js/no_unused_variables.rs @@ -76,6 +76,15 @@ declare_rule! { /// }; /// foo(); /// ``` + /// + /// ```ts + /// function used_overloaded(): number; + /// function used_overloaded(s: string): string; + /// function used_overloaded(s?: string) { + /// return s; + /// } + /// used_overloaded(); + /// ``` pub(crate) NoUnusedVariables { version: "0.9.0", name: "noUnusedVariables", @@ -96,7 +105,8 @@ fn is_typescript_unused_ok(binding: &JsIdentifierBinding) -> Option<()> { JsSyntaxKind::TS_METHOD_SIGNATURE_CLASS_MEMBER | JsSyntaxKind::TS_CALL_SIGNATURE_TYPE_MEMBER | JsSyntaxKind::TS_METHOD_SIGNATURE_TYPE_MEMBER - | JsSyntaxKind::TS_FUNCTION_TYPE => Some(()), + | JsSyntaxKind::TS_FUNCTION_TYPE + | JsSyntaxKind::TS_DECLARE_FUNCTION_DECLARATION => Some(()), _ => None, } } @@ -115,6 +125,7 @@ fn is_typescript_unused_ok(binding: &JsIdentifierBinding) -> Option<()> { } } JsSyntaxKind::TS_INDEX_SIGNATURE_PARAMETER => Some(()), + JsSyntaxKind::TS_DECLARE_FUNCTION_DECLARATION => Some(()), _ => None, } } diff --git a/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts b/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts index 34fa7fb8025..122a4acb4f1 100644 --- a/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts +++ b/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts @@ -7,6 +7,12 @@ class D { } console.log(new D()); +function unused_overloaded(): number; +function unused_overloaded(s: string): string; +function unused_overloaded(s?: string) { + return s; +} + // Valid interface A { @@ -35,3 +41,10 @@ function f(fn: (title: string) => boolean) { f(); export type Command = (...args: any[]) => unknown; + +function used_overloaded(): number; +function used_overloaded(s: string): string; +function used_overloaded(s?: string) { + return s; +} +used_overloaded(); diff --git a/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts.snap b/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts.snap index f002d28af4f..f9119f21805 100644 --- a/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts.snap +++ b/crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.ts.snap @@ -13,6 +13,12 @@ class D { } console.log(new D()); +function unused_overloaded(): number; +function unused_overloaded(s: string): string; +function unused_overloaded(s?: string) { + return s; +} + // Valid interface A { @@ -42,6 +48,13 @@ f(); export type Command = (...args: any[]) => unknown; +function used_overloaded(): number; +function used_overloaded(s: string): string; +function used_overloaded(s?: string) { + return s; +} +used_overloaded(); + ``` # Diagnostics @@ -81,4 +94,16 @@ warning[js/noUnusedVariables]: This parameter is unused. ``` +``` +warning[js/noUnusedVariables]: This function is unused. + ┌─ noUnusedVariables.ts:12:10 + │ +12 │ function unused_overloaded(s?: string) { + │ ----------------- + += note: Unused variables usually are result of incomplete refactoring, typos and other source of bugs. + + +``` + diff --git a/crates/rome_js_semantic/src/tests/assertions.rs b/crates/rome_js_semantic/src/tests/assertions.rs index 85ba6d7e374..7893886d80c 100644 --- a/crates/rome_js_semantic/src/tests/assertions.rs +++ b/crates/rome_js_semantic/src/tests/assertions.rs @@ -101,11 +101,7 @@ use std::collections::{BTreeMap, HashMap}; /// if(true) ;/*NOEVENT*/; /// ``` pub fn assert(code: &str, test_name: &str) { - let r = rome_js_parser::parse( - code, - 0, - SourceType::js_module().with_variant(rome_js_syntax::LanguageVariant::Jsx), - ); + let r = rome_js_parser::parse(code, 0, SourceType::tsx()); if r.has_errors() { let files = SimpleFile::new(test_name.to_string(), code.into()); diff --git a/crates/rome_js_semantic/src/tests/references.rs b/crates/rome_js_semantic/src/tests/references.rs index 64369e2b4cd..c841a4f7362 100644 --- a/crates/rome_js_semantic/src/tests/references.rs +++ b/crates/rome_js_semantic/src/tests/references.rs @@ -171,6 +171,13 @@ function f({a/*#A*/} = {a: [b/*READ B2*/,c/*READ C*/,d/*READ D*/]}, b/*#B2*/) { console.log(a/*READ A*/, b/*READ B3*/); } f()", + ok_function_overloading, + "function overloaded/*#A*/(): number; + function overloaded/*#B*/(s: string): string; + function overloaded/*#C*/(s?: string) { + return s; + } + overloaded/*READ C*/();", } // Imports diff --git a/website/src/docs/lint/rules/noUnusedVariables.md b/website/src/docs/lint/rules/noUnusedVariables.md index 4ec067094d9..138b7b556a6 100644 --- a/website/src/docs/lint/rules/noUnusedVariables.md +++ b/website/src/docs/lint/rules/noUnusedVariables.md @@ -144,3 +144,12 @@ function foo() { foo(); ``` +```ts +function used_overloaded(): number; +function used_overloaded(s: string): string; +function used_overloaded(s?: string) { + return s; +} +used_overloaded(); +``` +