Repository navigation
Suggestion: Allow ES6 export syntax in namespaces #39865
Description
TypeScript Version: typescript@4.0.0-dev.20200801
Search Terms: namespace, import, export, re-export, module
Code
import { Point } from "./Point";
export type Line = {
readonly p1: Point;
readonly p2: Point;
readonly points?: readonly [Point, ...(readonly Point[])];
};
export namespace Line {
export { Point } from "~/Point"; // TS says "Export declarations are not permitted in a namespace"
// `export { Point };` <-- Should also work.
}
type LinePoint = Line.Point;
// ^ Somehow this actually works, i.e. `LinePoint` equals `Point`Expected behavior:
Exporting from a namespace should mirror ES6 module exports, i.e. export { X }, export { X } from "...", and export * as NS from "..."
The lack of syntax for re-exports makes it very hard to use namespace/type/function merging abilities to represent nice APIs. Here's an example of what a module could look like if this was allowed...
// User.tsx
import { Admin } from "./Admin";
import { Member } from "./Member";
export type User = Admin | Member;
export type Props = { readonly user: User; };
export function User({ user }: Props) {
return Admin.isAdmin(user) ? <Admin admin={user} /> : <Member member={user} />;
}
export namespace User {
export { Admin, Member }; // Nice.
export const isAuthenticated = (user: User): boolean => true;
}
// Home.tsx
import { User } from "./User";
export function Home({ user }: User.Props) {
return <User.Admin admin={useAdmin()} />; // An example of what this enables.
}Actual behavior:
TypeScript says "Export declarations are not permitted in a namespace," even though it actually respects the export declaration outside of the namespace.
Playground Link:
https://www.typescriptlang.org/play/#code/HYQwtgpgzgDiDGEAEBBJBvAUEnSIA8YB7AJwBcl4jgoKQkBeJAIhGaRCkutoG5MAvpkyhIsBMgBCGbLgLFyGVEgH8hmKjQr5GSSQDoU+kLyA
Related Issues:
#20273
This issue showcases some of the syntax gymnastics needed to get around this issue.
#4529
#4529 (comment)
More examples of verbose workarounds.
#38041 (comment)
Ron Buckton (@rbuckton) Provides a nice example of what this could look like if enabled.
#38041 (comment)
My comment with another motivating example after the issue was closed.
Activity
[-]Allow ES6 export syntax in namespaces[/-][+]Suggestion: Allow ES6 export syntax in namespaces[/+]cruhl commentedon Aug 17, 2020
Mohamed Hegazy (@mhegazy) Blast from the past...
#4529 (comment)
There's finally an issue tracking this 😅
cruhl commentedon Aug 17, 2020
Here's more "in the wild" code I found showing the syntax noise needed to get around this...
Here's what it could look like...
Or even...
cruhl commentedon Aug 17, 2020
Here's another relevant discussion: #36684 (comment)
cruhl commentedon Aug 17, 2020
Relevant Stack Overflow issue: https://stackoverflow.com/questions/47500855/exporting-imports-as-a-namespace-with-typescript
cruhl commentedon Aug 17, 2020
Here's a repo someone created to demonstrate this issue, coincidently I used the same
Pointexample in this issue: https://github.com/danprince/ts-export-types-bugcruhl commentedon Aug 19, 2020
I just found out this works, but only in ambient contexts, which is bizarre:
todd-elvers commentedon Aug 19, 2020
This is also a feature I've been looking for.
I've done this more times than I'd like to admit:
Just to achieve
cruhl commentedon Aug 19, 2020
Another way to achieve this without new syntax would be to allow type and value imports to have the same name, as is common in other scenarios...
cruhl commentedon Aug 19, 2020
You can also basically achieve this, but with huge drawbacks, using classes:
douglas-sousa commentedon Oct 10, 2020
Sorry if this is the wrong place to ask but namespace will still be a thing to be worked on? I usually encounter deprecation messages when I use it and Storybook sends an error message telling me to configure babel if I want to use it.
Like Conner Ruhl (@cruhl), I also found namespace to be a nice way to organize data and keep it more semantic
// basic example
cruhl commentedon Jan 12, 2022
Andrew Branch (@andrewbranch) I apologize if tagging you directly isn't the right move, let me know if that's the case, but I was wondering if you could provide some insight since you recently closed another related issue.
This is still something I believe would be a useful change and I'm eager/willing to champion/help in whatever way I can. Any pointers for moving the issue forward? Thanks in advance!
cruhl commentedon Oct 25, 2022
This issue has popped up again:
#51109
todd-elvers commentedon Oct 25, 2022
If there's a good reason to not implement this feature I'd love to know about it. I feel as though I've seen this issue pop up a few times and it always gets closed with little-to-no explanation. I suppose if we could come up with a PR then maybe we could get some more in-depth feedback.
cruhl commentedon Oct 25, 2022
This amazingly works...



cruhl commentedon Oct 25, 2022
Wow, still too much syntax, but it's so much better than
export import Something = Something_...Fryuni commentedon Oct 26, 2023
Another use case is exporting values with keywords as names (like
returnortry). Those might be generated from an external specification and should keep the original names.cruhl's workaround works with some modification:
Quite a pain to write the generator for such scenarios
cruhl commentedon Nov 7, 2023
For reference, this is how I'm doing this nowadays...
https://github.com/Stability-AI/StableStudio/tree/main/packages/stablestudio-ui#%EF%B8%8F%E2%83%A3-domain-syntax
raythurnvoid commentedon Apr 29, 2025
At least this should be allowed