From dc6ae0f0ac2cba46424778e39fe50cced8e9b730 Mon Sep 17 00:00:00 2001 From: Cameron Clark Date: Mon, 9 Feb 2026 16:29:16 +0000 Subject: [PATCH] fix(source-type): don't treat `d.ts` as a declaration file --- crates/oxc_span/src/source_type.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/oxc_span/src/source_type.rs b/crates/oxc_span/src/source_type.rs index 3a3bf198f776f..bcdedfdc5fb6d 100644 --- a/crates/oxc_span/src/source_type.rs +++ b/crates/oxc_span/src/source_type.rs @@ -152,18 +152,19 @@ impl FileExtension { /// - `index.mts` -> false /// - `index.d.css.ts` -> true /// - `index.d.css.mts` -> false + /// - `d.ts` -> false + /// - `d.d.ts` -> true + /// - `d.css.mts` -> false pub fn is_ts_declaration(self, file_name: &str) -> bool { match self { // https://www.typescriptlang.org/tsconfig/#allowArbitraryExtensions // `{file basename}.d.{extension}.ts` // https://github.com/microsoft/TypeScript/issues/50133 - FileExtension::Ts => { - file_name[..file_name.len() - 3].split('.').rev().take(2).any(|c| c == "d") - } - FileExtension::Mts | FileExtension::Cts => - { - #[expect(clippy::case_sensitive_file_extension_comparisons)] - file_name[..file_name.len() - 4].ends_with(".d") + FileExtension::Ts => file_name.rfind(".d.").is_some_and(|i| i != 0), + #[expect(clippy::case_sensitive_file_extension_comparisons)] + FileExtension::Mts | FileExtension::Cts => { + let base_file_name = &file_name[..file_name.len() - 4]; + base_file_name.len() > 2 && base_file_name.ends_with(".d") } _ => false, } @@ -802,10 +803,16 @@ mod file_extension_tests { let cases = vec![ ("index.d.ts", true), ("index.ts", false), + ("d.ts", false), + (".d.ts", false), ("index.d.mts", true), ("index.mts", false), + ("d.mts", false), + (".d.mts", false), ("index.d.cts", true), ("index.cts", false), + ("d.cts", false), + (".d.cts", false), ("index.d.js", false), ("index.js", false), ("index.d.jsx", false),