Repository: swc-project/swc (rust)

Issue:
swc_ecma_codegen not rendering ArrowExpr return_type
### Describe the bug

swc_ecma_codegen does not render the `return_type` property of `ArrowExpr`

### Input code

```typescript
let cm = Lrc::new(SourceMap::default());
let code = {
	let mut buf = vec![];

	{
		let mut emitter = Emitter {
			cfg: swc_ecma_codegen::Config {
				..Default::default()
			},
			cm: cm.clone(),
			comments: None,
			wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
		};

		emitter
			.emit_module(&Module {
				body: vec![ModuleItem::Stmt(Stmt::Expr(ExprStmt {
					span: Default::default(),
					expr: boxed(Expr::Arrow(ArrowExpr {
						span: Default::default(),
						params: vec![],
						type_params: None,
						is_async: false,
						is_generator: false,
						body: BlockStmtOrExpr::Expr(boxed(Expr::Lit(Lit::Bool(Bool {
							span: Default::default(),
							value: true,
						})))),
						return_type: Some(TsTypeAnn {
							span: Default::default(),
							type_ann: boxed(TsType::TsLitType(TsLitType {
								span: Default::default(),
								lit: TsLit::Bool(Bool {
									span: Default::default(),
									value: true,
								}),
							})),
						}),
					})),
				}))],
				span: Default::default(),
				shebang: None,
			})
			.unwrap();
	}

	String::from_utf8_lossy(&buf).to_string()
};
```


### Config

```json
N/A
```


### Playground link

_No response_

### Expected behavior

The return type should be rendered if given, like it is for normal functions.

### Actual behavior

The return type is not rendered.

### Version

0.96.0 local, but issue also exists on the source of `main` branch

### Additional context

_No response_

Pull request:
fix(es/codegen): Fix codegen of ArrowExpr return_type
<!-- Note: CI script will automatically rebase your PR so please do not rebase unless required -->

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**Description:**
Adds a render for the return_type property of the ArrowExpr node. Impl copied from `emit_fn_trailing`.
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->


**Related issue (if exists):**
Fixes #4305 

Patch:
diff --git a/crates/swc_ecma_codegen/src/lib.rs b/crates/swc_ecma_codegen/src/lib.rs
index a471a27bd1..fa2f72297a 100644
--- a/crates/swc_ecma_codegen/src/lib.rs
+++ b/crates/swc_ecma_codegen/src/lib.rs
@@ -940,6 +940,13 @@ where
             punct!(")");
         }
 
+        if let Some(ty) = &node.return_type {
+            punct!(":");
+            formatting_space!();
+            emit!(ty);
+            formatting_space!();
+        }
+
         punct!("=>");
         emit!(node.body);
 


Test patch:
diff --git a/crates/swc_ecma_transforms_base/tests/ts-resolver/ts_type_parameter_used_as_type_parameter_contraint_01/output.ts b/crates/swc_ecma_transforms_base/tests/ts-resolver/ts_type_parameter_used_as_type_parameter_contraint_01/output.ts
index c8c644b02a..04771f6f2c 100644
--- a/crates/swc_ecma_transforms_base/tests/ts-resolver/ts_type_parameter_used_as_type_parameter_contraint_01/output.ts
+++ b/crates/swc_ecma_transforms_base/tests/ts-resolver/ts_type_parameter_used_as_type_parameter_contraint_01/output.ts
@@ -1,6 +1,6 @@
 var f3 = <T__2, U__2 extends T__2>(x__2: T__2, y__2: U__2)=>{
     function bar__2<V__3 extends T__2, W__3 extends U__2>() {
-        var g__3 = <X__4 extends W__3, Y__4 extends V__3>(a__4: X__4, b__4: Y__4)=>{
+        var g__3 = <X__4 extends W__3, Y__4 extends V__3>(a__4: X__4, b__4: Y__4): T__2 =>{
             x__2 = y__2;
             return y__2;
         };
@@ -8,7 +8,7 @@ var f3 = <T__2, U__2 extends T__2>(x__2: T__2, y__2: U__2)=>{
 };
 var f4 = <U__5 extends T__5, T__5>(x__5: T__5, y__5: U__5)=>{
     function bar__5<V__6 extends T__5, W__6 extends U__5>() {
-        var g__6 = <X__7 extends W__6, Y__7 extends V__6>(a__7: X__7, b__7: Y__7)=>{
+        var g__6 = <X__7 extends W__6, Y__7 extends V__6>(a__7: X__7, b__7: Y__7): T__5 =>{
             x__5 = y__5;
             return y__5;
         };
diff --git a/crates/swc_ecma_transforms_base/tests/ts-resolver/tsc/typeParameterUsedAsTypeParameterConstraint4.ts/output.ts b/crates/swc_ecma_transforms_base/tests/ts-resolver/tsc/typeParameterUsedAsTypeParameterConstraint4.ts/output.ts
index 461ced8a32..feccb925b8 100644
--- a/crates/swc_ecma_transforms_base/tests/ts-resolver/tsc/typeParameterUsedAsTypeParameterConstraint4.ts/output.ts
+++ b/crates/swc_ecma_transforms_base/tests/ts-resolver/tsc/typeParameterUsedAsTypeParameterConstraint4.ts/output.ts
@@ -29,7 +29,7 @@ function foo2<U__9 extends T__9, T__9>(x__9: T__9, y__9: U__9): W {
 }
 var f3 = <T__12, U__12 extends T__12>(x__12: T__12, y__12: U__12)=>{
     function bar__12<V__13 extends T__12, W__13 extends U__12>(r__13: X, s__13: Y) {
-        var g__13 = <X__14 extends W__13, Y__14 extends V__13>(a__14: X__14, b__14: Y__14)=>{
+        var g__13 = <X__14 extends W__13, Y__14 extends V__13>(a__14: X__14, b__14: Y__14): T__12 =>{
             x__12 = y__12;
             return y__12;
         };
@@ -37,7 +37,7 @@ var f3 = <T__12, U__12 extends T__12>(x__12: T__12, y__12: U__12)=>{
 };
 var f4 = <U__15 extends T__15, T__15>(x__15: V, y__15: X)=>{
     function bar__15<V__16 extends T__15, W__16 extends U__15>() {
-        var g__16 = <X__17 extends W__16, Y__17 extends V__16>(a__17: X__17, b__17: Y__17)=>{
+        var g__16 = <X__17 extends W__16, Y__17 extends V__16>(a__17: X__17, b__17: Y__17): T__15 =>{
             x__15 = y__15;
             return y__15;
         };
diff --git a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain/output.ts b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain/output.ts
index 3f34fdab47..83c0587d66 100644
--- a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain/output.ts
+++ b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain/output.ts
@@ -14,11 +14,11 @@ var f2 = function<U__5 extends T__5, T__5>(x__5: T__5, y__5: U__5): T__5 {
     x__5 = y__5;
     return y__5;
 };
-var f3 = <T__6, U__6 extends T__6>(x__6: T__6, y__6: U__6)=>{
+var f3 = <T__6, U__6 extends T__6>(x__6: T__6, y__6: U__6): T__6 =>{
     x__6 = y__6;
     return y__6;
 };
-var f4 = <U__7 extends T__7, T__7>(x__7: T__7, y__7: U__7)=>{
+var f4 = <U__7 extends T__7, T__7>(x__7: T__7, y__7: U__7): T__7 =>{
     x__7 = y__7;
     return y__7;
 };
diff --git a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_2/output.ts b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_2/output.ts
index 7e8fdb6cbc..c9dbdc5b2d 100644
--- a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_2/output.ts
+++ b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_2/output.ts
@@ -1,4 +1,4 @@
-var f3 = <T__2, U__2 extends T__2>(x__2: T__2, y__2: U__2)=>{
+var f3 = <T__2, U__2 extends T__2>(x__2: T__2, y__2: U__2): T__2 =>{
     x__2 = y__2;
     return y__2;
 };
diff --git a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_3/output.ts b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_3/output.ts
index 1d1b24631f..f81b1befea 100644
--- a/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_3/output.ts
+++ b/crates/swc_ecma_transforms_base/tests/ts-resolver/type_parameter_used_as_type_parameter_contrain_3/output.ts
@@ -1,4 +1,4 @@
-var f4 = <U__2 extends T__2, T__2>(x__2: T__2, y__2: U__2)=>{
+var f4 = <U__2 extends T__2, T__2>(x__2: T__2, y__2: U__2): T__2 =>{
     x__2 = y__2;
     return y__2;
 };
diff --git a/crates/swc_ecma_transforms_typescript/tests/strip.rs b/crates/swc_ecma_transforms_typescript/tests/strip.rs
index 990dd08dbe..d7945e4453 100644
--- a/crates/swc_ecma_transforms_typescript/tests/strip.rs
+++ b/crates/swc_ecma_transforms_typescript/tests/strip.rs
@@ -2114,7 +2114,7 @@ export default (identifier: string, level = 0, b = "", m = false) => {
     const proseTypes = new Map();
 
     // deno-lint-ignore ban-types
-    const prose = (l, i, nl, bp): string => {
+    const prose = (l, i, nl, bp) => {
         return i(l) + bp + "prose {" + nl +
             i(l + 1) + "color: #374151;" + nl +
             i(l + 1) + "max-width: 65ch;" + nl +
@@ -2407,7 +2407,7 @@ export default (identifier: string, level = 0, b = "", m = false) => {
     proseTypes.set("prose", prose);
 
     // deno-lint-ignore ban-types
-    const proseSm = (l, i, nl, bp): string => {
+    const proseSm = (l, i, nl, bp) => {
         return i(l) + bp + "prose-sm {" + nl +
             i(l + 1) + "font-size: 0.875rem;" + nl +
             i(l + 1) + "line-height: 1.7142857;" + nl +
@@ -2595,7 +2595,7 @@ export default (identifier: string, level = 0, b = "", m = false) => {
     proseTypes.set("prose-sm", proseSm);
 
     // deno-lint-ignore ban-types
-    const proseLg = (l, i, nl, bp): string => {
+    const proseLg = (l, i, nl, bp) => {
         return i(l) + bp + "prose-lg {" + nl +
             i(l + 1) + "font-size: 1.125rem;" + nl +
             i(l + 1) + "line-height: 1.7777778;" + nl +
@@ -2783,7 +2783,7 @@ export default (identifier: string, level = 0, b = "", m = false) => {
     proseTypes.set("prose-lg", proseLg);
 
     // deno-lint-ignore ban-types
-    const proseXl = (l, i, nl, bp): string => {
+    const proseXl = (l, i, nl, bp) => {
         return i(l) + bp + "prose-xl {" + nl +
             i(l + 1) + "font-size: 1.25rem;" + nl +
             i(l + 1) + "line-height: 1.8;" + nl +