From 9ab3c14c22a186e9f27db584f0ddb86b4073dafd Mon Sep 17 00:00:00 2001 From: "Arend van Beelen jr." Date: Wed, 16 Jul 2025 11:27:27 +0200 Subject: [PATCH] fix(linter): fix false positive with .d.ts files in useImportExtensions --- .changeset/damned-definitions-differ.md | 5 +++ .../lint/correctness/use_import_extensions.rs | 33 ++++++++++--------- .../sub/generated/index.d.ts | 1 + .../sub/generated/index.d.ts.snap | 9 +++++ .../sub/generated/index.js | 1 + .../sub/generated/index.js.snap | 9 +++++ .../correctness/useImportExtensions/valid.js | 2 ++ .../useImportExtensions/valid.js.snap | 2 ++ 8 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 .changeset/damned-definitions-differ.md create mode 100644 crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts create mode 100644 crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts.snap create mode 100644 crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js create mode 100644 crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js.snap diff --git a/.changeset/damned-definitions-differ.md b/.changeset/damned-definitions-differ.md new file mode 100644 index 000000000000..b9ffa3c3054e --- /dev/null +++ b/.changeset/damned-definitions-differ.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#6829](https://github.com/biomejs/biome/issues/6829): Fixed a false positive reported by `useImportExtensions` when importing a `.js` file that had a matching `.d.ts` file in the same folder. diff --git a/crates/biome_js_analyze/src/lint/correctness/use_import_extensions.rs b/crates/biome_js_analyze/src/lint/correctness/use_import_extensions.rs index 6b48d0b55697..2e1995ad0480 100644 --- a/crates/biome_js_analyze/src/lint/correctness/use_import_extensions.rs +++ b/crates/biome_js_analyze/src/lint/correctness/use_import_extensions.rs @@ -215,19 +215,22 @@ fn get_extensionless_import( return None; } - // In cases like `./foo.css` -> `./foo.css.ts` - let resolved_path_has_sub_extension = resolved_path - .file_stem() - .is_some_and(|stem| stem.contains('.')); - let existing_extension = path.extension(); + let resolved_stem = resolved_path.file_stem(); + let resolved_extension = resolved_path.extension(); + let resolved_path_sub_extension = + resolved_stem.and_then(|stem| stem.rfind('.').map(|pos| &stem[pos + 1..])); - if resolved_path_has_sub_extension && path.file_name()?.starts_with(resolved_path.file_name()?) - { - return None; - } + let existing_extension = path.extension(); - if !resolved_path_has_sub_extension && existing_extension.is_some() { - return None; + match (resolved_path_sub_extension, existing_extension) { + (Some("d"), Some("js")) if resolved_extension.is_some_and(|ext| ext == "ts") => { + return None; // We resolved a `.d.ts` file, but imported the `.js` file: OK. + } + (Some(_), _) if path.file_name()?.starts_with(resolved_path.file_name()?) => { + return None; // For cases like `./foo.css` -> `./foo.css.ts` + } + (None, Some(_)) => return None, + _ => {} } let last_component = path_components.next_back().unwrap_or(first_component); @@ -244,12 +247,10 @@ fn get_extensionless_import( let extension = if force_js_extensions { "js" } else { - resolved_path.extension()? + resolved_extension? }; - let is_index_file = resolved_path - .file_stem() - .is_some_and(|stem| stem == "index"); + let is_index_file = resolved_stem.is_some_and(|stem| stem == "index"); let new_path = if is_index_file { let mut path_parts = path.as_str().split('/'); @@ -274,7 +275,7 @@ fn get_extensionless_import( new_path } else { let mut new_path = path.to_path_buf(); - let sub_extension = if resolved_path_has_sub_extension { + let sub_extension = if resolved_path_sub_extension.is_some() { existing_extension } else { None diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts new file mode 100644 index 000000000000..7b0de118191a --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts @@ -0,0 +1 @@ +/* should not generate diagnostics */ diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts.snap b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts.snap new file mode 100644 index 000000000000..ae8b91e4a5ff --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.d.ts.snap @@ -0,0 +1,9 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: index.d.ts +--- +# Input +```ts +/* should not generate diagnostics */ + +``` diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js new file mode 100644 index 000000000000..7b0de118191a --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js @@ -0,0 +1 @@ +/* should not generate diagnostics */ diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js.snap b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js.snap new file mode 100644 index 000000000000..db761a5707c5 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/sub/generated/index.js.snap @@ -0,0 +1,9 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: index.js +--- +# Input +```js +/* should not generate diagnostics */ + +``` diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js index 15311b73c4b0..298047da9967 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js @@ -25,3 +25,5 @@ import "./sub/component.svg.svelte.ts?query=string&query2#hash"; import './sub/baz'; import './sub/baz.css'; import './sub/baz.css.com'; + +import "./sub/generated/index.js"; diff --git a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js.snap b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js.snap index 3b592e983156..b64512692cc9 100644 --- a/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js.snap +++ b/crates/biome_js_analyze/tests/specs/correctness/useImportExtensions/valid.js.snap @@ -32,4 +32,6 @@ import './sub/baz'; import './sub/baz.css'; import './sub/baz.css.com'; +import "./sub/generated/index.js"; + ```