Repository: babel/babel (TypeScript)

Issue:
[Bug]: export namespace compiled failed in create-react-app
### 💻

- [ ] Would you like to work on a fix?

### How are you using Babel?

babel-loader (webpack)

### Input code

test-ts.ts
```
export namespace RuntimeStatus {

	export namespace Progress {
		export interface Quantity {
		  total?: number;
		  completed?: number;
		  unit?: string;
		}
		// export const a = '1';
	}

	export enum Severity {
		UNSPECIFIED = 0,
		NOTICE = 1,
		WARNING = 2,
		ERROR = 3,
		CRITICAL = 4,
	}
}
```

App.tsx
```
import './App.css';
import { RuntimeStatus } from './test-ts';

const a: RuntimeStatus.Progress.Quantity = {
  total: RuntimeStatus.Severity.ERROR
};
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}
```

### Configuration file name

.babelrc

### Configuration

_No response_

### Current and expected behavior


## Reproduce steps:

create a new project from create-react-app@5
add test-ts.ts file like above and import this file at a *.tsx file
then it report an error, but i think it shouldn't has error.

## Current behavior:
![image](https://github.com/babel/babel/assets/24775952/8f52846a-be8e-42cf-a791-bbceb06f1e2c)


## Expected behavior
it shouldn't has error report


### Environment

- System:
    OS: macOS 12.0.1

- Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.7.0 - /usr/local/bin/yarn
    npm: 8.5.0 - /usr/local/bin/npm

- npm Packages:
    @babel/plugin-proposal-private-property-in-object: ^7.21.11 => 7.21.11 
    babel-loader: 9.1 => 9.1.3 
    eslint: ^8.46.0 => 8.47.0 


### Possible solution

_No response_

### Additional context

reproduce lib:
https://github.com/yangguansen/typescript-bug-report


Hints:
Hey @yangguansen! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant [Slack community](https://babeljs.slack.com) that typically always has someone willing to help. You can sign-up [here](https://slack.babeljs.io/) for an invite.
Hello,
Looks like this issue isn't unique to CRA - I encountered it in React Native. 
After upgrading my app from RN 0.68.4 to 0.72.4 I got compile errors in one file where we had our API typings.
It was structured as such:
```typescript
export namespace API {
    export namespace Foo1 {
        export namespace Bar1 {
         export type Payload = {
            // ...
         }
         export type Response = {
            // ...
         }
        }
        export namespace Bar2 {
           // ...
        }
    }
    export namespace Foo2 {
         // ...
    }
}
```
We would type some variable like this:
```typescript
const foo:API.Foo1.Bar1.Payload = 'bar'
```

I am not sure about 0.68.4, but in 0.72.4 babel would compile it to something like:
```javascript
var API;
exports.API = API;
(function (_API) {
   export var Foo1; //this line would error out
   export var Foo2;
}
)
```

I figured out I can bypass this error (hopefully it won't be needed in the future!) by not-really-nesting namespaces:

```typescript
export namespace API.Foo1 {
    export namespace Bar1 {
        export type Payload = {
        // ...
        }
        export type Response = {
        // ...
        }
    }
    export namespace Bar2 {
        // ...
    }
}
export namespace API.Foo2 {
        // ...
}
```

It does work, but in places where I had more nestings I would have to specify them all out, which is less than ideal:
```typescript
export namespace API.Foo1.Bar1.Baz1 {
  export type Payload = {
    //...
   }
}
```

I hope this helps with the investigation!
@liuxingbaoyu I noticed that you assigned this issue to yourself, but "Would you like to work on a fix?" has been selected :)
Sorry that i selected the checkbox "Would you like to work on a fix?"， I hope that who can fix this, many thanks!
I try to compile type code in the typescript playground, and it can compiled correctly , but no correctly with CRA@5, this is the result
![image](https://github.com/babel/babel/assets/24775952/d7da4da6-2195-458d-b953-34f31e5ec787)

I hope this can have a little  bit help to how to help this
@yangguansen If you are interested, you are welcome to submit a PR to fix this :) (If you cannot don't worry, somebody else will do it)

The bug is probably in https://github.com/babel/babel/blob/0c8dfc1bd77e807e08bada82eeee90b0e68d4c2f/packages/babel-plugin-transform-typescript/src/namespace.ts#L226-L233. When we have a nested `export namespace`, if its contents are not transformed (i.e. if it only contains type-level declarations, such as interfaces) we simply do nothing. Instead, if `transformed` is `null`, we should remove it by removing `namespaceTopLevel[i]` from `namespaceTopLevel`.

---

<!-- ALERT!!!!!!!
    Before submitting this comment, please:
      1. Write where to start searching the bug
      2. Write where to add a new test
    See https://github.com/babel/babel/issues/9563#issuecomment-466799807 for an example
-->

If it is the first time that you contribute to Babel, follow these steps: (you need to have `make` and `yarn` available on your machine)
1. **Write a comment there** to let other possible contributors know that you are working on this bug.
1. Fork the repo
1. Run `git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel`
1. Run `yarn && make bootstrap`
1. Wait :hourglass_flowing_sand: 
1. Run `make watch` (or `make build` whenever you change a file)
1. Add a test in `packages/babel-plugin-transform-typescript/test/fixtures/namespace` (only `input.ts`; `output.js` will be automatically generated)
1. Update the code!
1. `yarn jest typescript` to run the tests
    - If some test outputs don't match but the new results are correct, you can delete the bad `output.js` files and run the tests again
    - If you prefer, you can run `OVERWRITE=true yarn jest typescript` and they will be automatically updated.
1. If it is working, run `make test` to run all the tests
1. Run `git push` and open a PR!
Wow, appreciate for giving these amazing suggestions  to me ,  I will take a look at this to research the related code , and this is my first time to touch Babel source code, I'm not sure I can solve the issue in future days but i will take some effort on this, welcome other guys to take this as well  :)
Feel free to ask for help here if needed!
Oops I didn't notice this before. :)
Luckily I just looked into it and haven't actually written the code to fix it yet.
Glad to see you're willing to do this, let me know if there's anything I can help with, I'd love to!
I simply add a sentence at [babel/packages/babel-plugin-transform-typescript/src/namespace.ts](https://github.com/babel/babel/blob/0c8dfc1bd77e807e08bada82eeee90b0e68d4c2f/packages/babel-plugin-transform-typescript/src/namespace.ts#L226-L233)
that @nicolo-ribaudo mentioned , it can compiled correctly, 
<img width="630" alt="image" src="https://github.com/babel/babel/assets/24775952/d93fe4f2-dd7b-425f-8cd5-c8013d092bc6">

but when i run `make test` to run all tests, it displayed  this error, it seems that logic exist in `executor.js`
```
setTimeout(() => {
  console.error("EXECUTOR TIMEOUT");
  process.exit(1);
}, 5000);
```
<img width="1054" alt="image" src="https://github.com/crafting-dev/sandbox-ui/assets/24775952/f8eaf8cd-1d6e-4fc8-8c52-3c239e4bf559">

Could someone let me know what's the reason about this test timeout error?
Feel free to ignore that failure -- for some reason that test sometimes fails but only when running all the tests, and never on CI 😅 

Patch:
diff --git a/packages/babel-plugin-transform-typescript/src/namespace.ts b/packages/babel-plugin-transform-typescript/src/namespace.ts
--- a/packages/babel-plugin-transform-typescript/src/namespace.ts
+++ b/packages/babel-plugin-transform-typescript/src/namespace.ts
@@ -242,6 +242,9 @@ function handleNested(
               transformed,
             );
           }
+        } else {
+          namespaceTopLevel.splice(i, 1);
+          i--;
         }
       }
     }


Test patch:
diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/input.ts
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/input.ts
@@ -0,0 +1,13 @@
+export namespace A {
+  export namespace B {
+    export interface C {
+      D?: number;
+      E?: number;
+      F?: string;
+    }
+  }
+
+  export enum G {
+    H = 0
+  }
+}
diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/output.mjs b/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/output.mjs
new file mode 100644
--- /dev/null
+++ b/packages/babel-plugin-transform-typescript/test/fixtures/namespace/nested-namespace/output.mjs
@@ -0,0 +1,8 @@
+export let A;
+(function (_A) {
+  let G = /*#__PURE__*/function (G) {
+    G[G["H"] = 0] = "H";
+    return G;
+  }({});
+  _A.G = G;
+})(A || (A = {}));