-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support type-only/uninstantiated namespaces #32
Conversation
Signed-off-by: Ashley Claymore <[email protected]>
Signed-off-by: Ashley Claymore <[email protected]>
Signed-off-by: Ashley Claymore <[email protected]>
Co-authored-by: Rob Palmer <[email protected]> Signed-off-by: Ashley Claymore <[email protected]>
} | ||
|
||
namespace With.Imports { | ||
import Types = My.Internal.Types; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our one-pass design (SWC), while optimal for speed, inherently defers complex symbol resolution — a trade-off that aligns with tsc's isolatedModules for explicit import type
syntax in ESM interactions.
However, this architecture faces new challenges as we now support namespaces. Unlike ESM's enforced type/value distinction, namespace imports/exports (e.g., My.Internal.Types
) require non-trivial static analysis to resolve ambiguities:
- Prior Approach: Namespaces were ignored, sidestepping the need for deep resolution.
- Current Need: Determining if
Types
is a value or type within namespaces demands preliminary metadata collection, contradicting our single-scan constraint.
Adopting TypeScript syntax that mirrors ESM's explicitness — such as:
import type Types = My.Internal.Types; // namespace type binding
— would extend the same design principle to namespaces. By declaring intent upfront, the compiler could resolve symbols in a single pass without heuristic fallbacks, bridging the gap between ESM rigor and namespace flexibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HI @magic-akari
ts-blank-space
is the same, there is no symbol resolution.
I should have made the test case clearer. All ImportEqual
statements are OK and do not count as an instantiated namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #38 to add more test cases.
This PR adds support for type-only/uninstantiated namespaces. i.e. namespaces that only use
type
andinterface
.Before: Error. only
declare namespace ...
was allowed ❌Now: Ok. namespace declaration erased ✅
The following cases remain unchanged:
Testing
Unit tests for both supported cases and unsupported cases (errors) have been added.
Context
This addition was motivated by
--erasableSyntaxOnly
and the recognition that in today's TypeScript, the only way to augment a class with types after the initial declaration is via namespaces. Whilst that use case can be solved usingdeclare namespace
that comes with a hazard. The combination of--erasableSyntaxOnly
checks and transforming uninstantiated namespaces provides a safer option.Thanks to @jakebailey for bringing this to our attention microsoft/TypeScript#61011 (comment)