Repository: swc-project/swc (rust)

Issue:
Export assignment retains function types
### Describe the bug

When using the `export =` assignment syntax to mimic `module.exports` behavior as described [here in the handbook](https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require), the transpilation leaves the types on a function, which will cause any ECMAScript runtime to crash on loading the code.

### Input code

```typescript
export = function (foo: string, bar: number): boolean {
  return true
}
```


### Config

```json
Default CLI invocation
```


### Playground link

https://swc-play.vercel.app/?version=1.2.106&code=H4sIAAAAAAAAAwXBQQqAMAwEwHtfsUcFX1DwMY2kUtBE1gQE8e%2FO6HM5Ayt62hbDDVN3r7iDw%2FYF0lhheYpyrhD3Q5vhLQA1koZgavl%2BrzUIy0cAAAA%3D&config=H4sIAAAAAAAAA0WNSwrDMAxE76J1ts0id%2BghjKsEF%2F%2FQKBBjfPfawSU7aebpqdIXlrZK2QhYxoQS1Vy0kZbMsOKy0kKKHu3Gg1tfjBysHWG8eudTAs92oeCi28sw2RSyMPBUJh7%2BT7YuCulzjqDez27hSu1xzDuH9wRVTm4%2FOkwQUrUAAAA%3D

### Expected behavior

```javascript
module.exports = function(foo, bar) {
  return true;
};

// Not sure whether this is another bug, but I would expect a single form of exports
export { };
```

### Version

v1.2.94 and above

### Additional context

It used to work up until 1.2.93 and is broken since.

A workaround is to use `export default` and change the usage of the code accordingly, e.g. `require('./module').default`

Pull request description:
fix(es/transforms/strip): Strip types for typescript export equals
- closes #2613 

This PR attempts to close #2613 which retains typescript signatures if export is TsExportAssignment, by letting expr visits itself.

The other behavior noted in issue (empty `export {}`) looks like related with ESM output target. It may dealt separately if it need to be fixed.

Patch:
diff --git a/ecmascript/transforms/typescript/src/strip.rs b/ecmascript/transforms/typescript/src/strip.rs
index b2d5181680..4947e9b6a7 100644
--- a/ecmascript/transforms/typescript/src/strip.rs
+++ b/ecmascript/transforms/typescript/src/strip.rs
@@ -2158,7 +2158,9 @@ where
                     }
                 }
 
-                ModuleItem::ModuleDecl(ModuleDecl::TsExportAssignment(export)) => {
+                ModuleItem::ModuleDecl(ModuleDecl::TsExportAssignment(mut export)) => {
+                    export.expr.visit_mut_with(self);
+
                     stmts.push(ModuleItem::Stmt(Stmt::Expr(ExprStmt {
                         span: export.span,
                         expr: Box::new(Expr::Assign(AssignExpr {


Test patch:
diff --git a/ecmascript/transforms/typescript/tests/strip.rs b/ecmascript/transforms/typescript/tests/strip.rs
index 532bd22202..761eb09e46 100644
--- a/ecmascript/transforms/typescript/tests/strip.rs
+++ b/ecmascript/transforms/typescript/tests/strip.rs
@@ -4176,6 +4176,20 @@ test_with_config!(
     "
 );
 
+to!(
+    issue_2613,
+    "
+    export = function (foo: string, bar: number): boolean {
+        return true
+    };
+    ",
+    "
+    module.exports = function (foo, bar) {
+        return true
+    };
+    "
+);
+
 #[testing::fixture("tests/fixture/**/input.ts")]
 #[testing::fixture("tests/fixture/**/input.tsx")]
 fn exec(input: PathBuf) {
diff --git a/tests/fixture/issue-2613/1/input/.swcrc b/tests/fixture/issue-2613/1/input/.swcrc
new file mode 100644
index 0000000000..68afad7fa4
--- /dev/null
+++ b/tests/fixture/issue-2613/1/input/.swcrc
@@ -0,0 +1,10 @@
+{
+  "jsc": {
+    "parser": {
+      "syntax": "typescript"
+    }
+  },
+  "module": {
+    "type": "commonjs"
+  }
+}
\ No newline at end of file
diff --git a/tests/fixture/issue-2613/1/input/index.ts b/tests/fixture/issue-2613/1/input/index.ts
new file mode 100644
index 0000000000..56269d82f1
--- /dev/null
+++ b/tests/fixture/issue-2613/1/input/index.ts
@@ -0,0 +1,3 @@
+export = function (foo: string, bar: number): boolean {
+  return true
+}
\ No newline at end of file
diff --git a/tests/fixture/issue-2613/1/output/index.ts b/tests/fixture/issue-2613/1/output/index.ts
new file mode 100644
index 0000000000..ce456a9e98
--- /dev/null
+++ b/tests/fixture/issue-2613/1/output/index.ts
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+module.exports = function(foo, bar) {
+    return true;
+};