diff --git a/crates/oxc_formatter/src/print/type_parameters.rs b/crates/oxc_formatter/src/print/type_parameters.rs index 85e39ff63a32c..7660f5121f13c 100644 --- a/crates/oxc_formatter/src/print/type_parameters.rs +++ b/crates/oxc_formatter/src/print/type_parameters.rs @@ -1,5 +1,6 @@ use oxc_allocator::Vec; use oxc_ast::ast::*; +use oxc_span::FileExtension; use crate::{ ast_nodes::{AstNode, AstNodes}, @@ -71,10 +72,17 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, TSTypeParameter<'a>>> { // to avoid any ambiguity with JSX elements. // Thus, we have to add a trailing comma when there is a single type parameter. // The comma can be omitted in the case where the single parameter has a constraint, - // i.i. an `extends` clause. + // i.e. an `extends` clause. + // + // This applies to: + // - JSX files (`.jsx`, `.tsx`) where `` could be parsed as a JSX element + // - `.mts` and `.cts` files which disallow JSX-like syntax without disambiguation let trailing_separator = if self.len() == 1 - // This only concern sources that allow JSX or a restricted standard variant. - && f.context().source_type().is_jsx() + && (f.context().source_type().is_jsx() + || matches!( + f.context().source_type().extension(), + Some(FileExtension::Mts | FileExtension::Cts) + )) && matches!(self.grand_parent(), AstNodes::ArrowFunctionExpression(_)) // Ignore Type parameter with an `extends` clause or a default type. && !self.first().is_some_and(|t| t.constraint().is_some() || t.default().is_some()) diff --git a/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts new file mode 100644 index 0000000000000..4f65bad95f4a7 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts @@ -0,0 +1,8 @@ +// Single type parameter in arrow function requires trailing comma in .cts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; diff --git a/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts.snap b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts.snap new file mode 100644 index 0000000000000..7588f159ba3a8 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-cts.cts.snap @@ -0,0 +1,39 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +// Single type parameter in arrow function requires trailing comma in .cts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +==================== Output ==================== +------------------ +{ printWidth: 80 } +------------------ +// Single type parameter in arrow function requires trailing comma in .cts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +------------------- +{ printWidth: 100 } +------------------- +// Single type parameter in arrow function requires trailing comma in .cts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +===================== End ===================== diff --git a/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts new file mode 100644 index 0000000000000..ec9ac33f3806a --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts @@ -0,0 +1,8 @@ +// Single type parameter in arrow function requires trailing comma in .mts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; diff --git a/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts.snap b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts.snap new file mode 100644 index 0000000000000..7e279d1b6975b --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/trailing-comma/issue-18924-mts.mts.snap @@ -0,0 +1,39 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +// Single type parameter in arrow function requires trailing comma in .mts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +==================== Output ==================== +------------------ +{ printWidth: 80 } +------------------ +// Single type parameter in arrow function requires trailing comma in .mts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +------------------- +{ printWidth: 100 } +------------------- +// Single type parameter in arrow function requires trailing comma in .mts files +const fn = () => {}; + +// With constraint - no trailing comma needed +const fn2 = () => {}; + +// Multiple type parameters - no special handling needed +const fn3 = () => {}; + +===================== End =====================