Skip to content
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

Support “Arbitrary module namespace identifier names” #40594

Closed
5 tasks done
ExE-Boss opened this issue Sep 16, 2020 · 18 comments · Fixed by #58640
Closed
5 tasks done

Support “Arbitrary module namespace identifier names” #40594

ExE-Boss opened this issue Sep 16, 2020 · 18 comments · Fixed by #58640
Labels
Domain: ES Modules The issue relates to import/export style module behavior Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". ES Next New featurers for ECMAScript (a.k.a. ESNext) Fix Available A PR has been opened for this issue Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros Help Wanted You can do this Rescheduled This issue was previously scheduled to an earlier milestone Suggestion An idea for TypeScript

Comments

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Sep 16, 2020

Search Terms

  • Arbitrary module namespace identifier names
  • Arbitrary module namespace identifiers
  • Arbitrary module identifier names
  • Arbitrary module identifiers
  • Arbitrary module identifier
  • Arbitrary export names
  • Arbitrary export identifiers
  • string export names
  • string exports

Suggestion

Implement support for tc39/ecma262#2154.

Use Cases

This is necessary for WASM module integration.

This would also allow typing @types/webidl‑conversions without needing to use export =.


For transpiled modules, this can already be supported, since it’s just creation of arbitrary properties on the CommonJS exports object, but native modules will require module: "ESNext".

Examples

See tc39/ecma262#2154

// @showEmit
// @filename: module.d.ts
export const foo: unknown;

declare const some_imports: unknown;
export { some_imports as "some imports" };

declare const another_imports: unknown;
export { another_imports as "another imports" };

declare const extra_imports: unknown;
export { extra_imports as "extra imports" };

declare const rest_exports: unknown;
export { rest_exports as "rest exports" };

// @filename: index.ts
import { "some imports" as foo } from "./module.js";

export { foo as "some exports" } from "./module.js";
export { "another imports" as "another exports" } from "./module.js";
export { "rest exports" } from "./module.js";
export { "extra imports" as extra_imports } from "./module.js";

export * as "star exports" from "./module.js";

Workbench Repro

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Related issues

@DanielRosenwasser DanielRosenwasser added ES Next New featurers for ECMAScript (a.k.a. ESNext) Waiting for TC39 Unactionable until TC39 reaches some conclusion labels Sep 16, 2020
@ExE-Boss
Copy link
Contributor Author

Note that Babel now has support for this: babel/babel#12091

@typescript-bot typescript-bot added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label Feb 16, 2021
@DanielRosenwasser DanielRosenwasser added Domain: ES Modules The issue relates to import/export style module behavior Committed The team has roadmapped this issue and removed Waiting for TC39 Unactionable until TC39 reaches some conclusion labels May 9, 2021
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 4.4.0 milestone May 9, 2021
@DanielRosenwasser
Copy link
Member

tc39/ecma262#2154

import { "😊" as yay } from "...";

yay();

export { yay as "🦈" };

The above code should be supported.

The minimum viable product should have tests for:

  • esnext module output
  • es2015 or similar module output just to get an error
  • --declaration emit
    • Specific declaration emit where the compiler might generate import() type syntax.
  • Quick info, and error message tests where we might generate import() type syntax
  • Completions in import {} and export {} lists
  • Go-to-definition

It is likely that we would never try to emit our own import() type syntax.

@DanielRosenwasser DanielRosenwasser added the Suggestion An idea for TypeScript label May 9, 2021
@andrewbranch andrewbranch added the Rescheduled This issue was previously scheduled to an earlier milestone label Aug 30, 2021
@evanw
Copy link
Contributor

evanw commented Sep 28, 2021

Is it planned for this to work with TypeScript types as well as values? For example, I'd expect the following to be valid as well:

import type { 'a' as b } from 'foo' 
import { type 'a' as b } from 'foo' 

export type { a as 'b' }
export { type a as 'b' }
export { type 'a' } from 'foo' 
export { type 'a' as b } from 'foo' 
export { type a as 'b' } from 'foo' 
export { type 'a' as 'b' } from 'foo' 

I'm wondering because esbuild supports both TypeScript and arbitrary module namespace identifier names, so it has to deal with this somehow. Right now I'm moving forward assuming that it will eventually be supported for types as well but it would be good to clarify this.

@andrewbranch
Copy link
Member

@evanw I’m pretty sure your examples above will “just work” unless we explicitly disallow them, and I don’t see an immediate reason to do that. The syntax above would certainly parse. Just out of curiosity, what’s the impact of this on esbuild?

@andrewbranch
Copy link
Member

@DanielRosenwasser should this actually be milestoned right now? It’s a bit hard to tell the status of the spec change, but it looks kinda stuck.

@DanielRosenwasser
Copy link
Member

Good call, I assumed it would be an open-and-shut normative PR but it looks like it hasn't been updated for a while; let's hold off until tc39/ecma262#2154 is actually merged.

@andrewbranch andrewbranch added Waiting for TC39 Unactionable until TC39 reaches some conclusion and removed Committed The team has roadmapped this issue Rescheduled This issue was previously scheduled to an earlier milestone labels Oct 1, 2021
@andrewbranch andrewbranch removed this from the TypeScript 4.6.0 milestone Oct 1, 2021
eduardomourar added a commit to eduardomourar/jco that referenced this issue Feb 15, 2023
This prepares the ground for when TypeScript will have
support for "Arbitrary module namespace
identifier names":
microsoft/TypeScript#40594
guybedford added a commit to bytecodealliance/jco that referenced this issue Feb 17, 2023
* fix: invalid names in import object

This prepares the ground for when TypeScript will have
support for "Arbitrary module namespace
identifier names":
microsoft/TypeScript#40594

* chore: define import object as interface and not namespace

---------

Co-authored-by: Eduardo Rodrigues <eduardomourar@users.noreply.github.com>
Co-authored-by: Guy Bedford <gbedford@fastly.com>
@Jack-Works
Copy link
Contributor

Some progress: I recently rewrite PR for this issue. I also plan to include full support (checker, transpiler, and language service).

I'm still working on it.

laverdet added a commit to laverdet/css-modules-typescript-loader that referenced this issue Oct 24, 2023
BREAKING CHANGE: Updates the declaration template.

This is a followup on seek-oss#38

The `exports =` declaration was added in e7342df but removed in
908d491 due some issue in babel which I can't reproduce. Maybe that
has been fixed downstream in the meantime.

Due to microsoft/TypeScript#40594 we cannot export these names directly
since class names might not be valid JavaScript identifiers, even though
they are valid exported names. When that TypeScript bug is resolved this
can be changed to export the names directly instead of using `export =`.
The problem with `export =` is that it will let you do `import * as css
from ...` in addition to `import css from ...` even though only
`import *` will work.
@evanw
Copy link
Contributor

evanw commented May 24, 2024

(For those on this thread) I gave fixing this a try: #58640

@Jack-Works
Copy link
Contributor

(For those on this thread) I gave fixing this a try: #58640

I'm happy to see you pick this up! My mental health does not support me finishing my PR for now but I still want to see this happen

@DanielRosenwasser
Copy link
Member

Thanks @evanw!

@evanw
Copy link
Contributor

evanw commented Jun 8, 2024

Thank you for accepting this PR. I'm looking forward to using this feature in VSCode!

One potential remaining task is syntax highlighting. I have another PR ready to go that adds support for this feature to the TypeScript language syntax definition: microsoft/TypeScript-TmLanguage#1030. Would it be possible to add that or a similar change (doesn't have to be mine) so that syntax highlighting works too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: ES Modules The issue relates to import/export style module behavior Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". ES Next New featurers for ECMAScript (a.k.a. ESNext) Fix Available A PR has been opened for this issue Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros Help Wanted You can do this Rescheduled This issue was previously scheduled to an earlier milestone Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants