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

Don't use declare module for TypeScript types #127

Merged

Conversation

alangpierce
Copy link
Collaborator

As I understand things, the declare module TypeScript syntax creates a
globally-importable name and says that any import with that name maps to the
given type. This means it usually works for libraries, but breaks down when
you have multiple versions of the same library loaded, since they each redefine
the same global name. It's really meant for things like Node.js built-in
modules. Instead, .d.ts files in libraries should just do exports at the
top-level, and TypeScript allows different versions of the same library to
peacefully coexist in that case.

I ran into a dependency hell problem that I think was caused by this issue where
decaffeinate pulled in three different versions of magic-string that conflicted.
I was able to change the dependency tree so it's just one version, which works
in the near term, but this change should prevent that from happening again.

As I understand things, the `declare module` TypeScript syntax creates a
globally-importable name and says that any import with that name maps to the
given type. This means it usually works for libraries, but breaks down when
you have multiple versions of the same library loaded, since they each redefine
the same global name. It's really meant for things like Node.js built-in
modules. Instead, `.d.ts` files in libraries should just do exports at the
top-level, and TypeScript allows different versions of the same library to
peacefully coexist in that case.

I ran into a dependency hell problem that I think was caused by this issue where
decaffeinate pulled in three different versions of magic-string that conflicted.
I was able to change the dependency tree so it's just one version, which works
in the near term, but this change should prevent that from happening again.
@Rich-Harris
Copy link
Owner

Ah, interesting. I think this may have been something to do with the fact that the ES module and the UMD module are slightly different (the ESM has a default and a named export, the CJS has a single module.exports, and Bundle is attached to it), and TypeScript was choking in VSCode because of that fact. Do you know if everything still behaves as expected with this change?

@alangpierce
Copy link
Collaborator Author

I think this is unrelated to the ES modules vs CJS issue. (Sounds like you're referring to #121?) When TypeScript sees export default in the type definition of a module, it expects to see a CJS module and generates code accessing its default property, but this PR doesn't change any of that.

With this change, it's defining the same TypeScript module as before, but rather than saying "associate the module with the global name magic-string", it's saying "associate the module with this particular package, regardless of where it lives in the node_modules tree".

(But I'm pretty new to TypeScript, so I might be misunderstanding some aspects of it. But I did test this change and it seems to still work. :-) )

I hadn't tried VSCode, but I tried just now (with npm link) and seems to pick up the types just fine after this change.

@Rich-Harris Rich-Harris merged commit be7c74e into Rich-Harris:master Jul 8, 2017
@Rich-Harris
Copy link
Owner

Cool — let's roll with it then and cross those bridges if we come to them. Thanks, releasing an update

@alangpierce
Copy link
Collaborator Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants