-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Module augmentation difficulties with AMD/CommonJS/globals #7015
Comments
At least for modules, top level exports are immutable in ES6, while their members are not. IMO, it makes sense that the restriction matches this. |
@weswigham should that restriction apply to systems using AMD (or commonjs) loading? Or to global augmentations? |
Augmenting modules seem unnecessarily strict and directed. Even trying to augment your own |
ES6 modules are the standard now; though not implemented :), i do not see why we need to diverge in semantics based on the output system. In your example, the original .d.ts (JQuery) can add the
I do not see why not. this is something we talked about as a desired feature, and we can definitely enable that. |
@mhegazy so even if a project sets Sure ES6 modules are now the standard, but they still have virtually no runtime support. AMD and CommonJS will be around the many years to come. TypeScript claims to support AMD and CommonJS. Why impose a restriction that doesn't apply to these module systems? This either prevents TypeScript from being able to type existing JavaScript patterns, or prevents moving away from global ambient module declarations. I'm still curious what's the upside of this decision, either for TypeScript, or the for many AMD/CommonJS projects out there? |
I think Option2 should work. today you need to have knowledge of the jquery.d.ts or react.d.ts to be able to extend it anyways, so not see why this is a limitation. and any change the base .d.ts will break your extension, again just like today.
limit complexity, unless it is absolutely necessary :) |
OK, but if you remove this restriction for the
I think you may underestimate the pain factor of this. Once module augmentations landed, I looked forward to removing hacks from some of our module declarations, in particular global ambient module declarations. I quickly discovered that I couldn't do that because of the killer combination of (a) can't add top-level decls (b) the manner in which many third-party typings are already written. |
@mhegazy @weswigham can you help me to work out how to use Option 2 in practice for a lib like jQuery, with AMD loading? I've tried the following approaches without success: First attemptThe following doesn't work because it relies on // File: jquery.d.ts
export interface JQueryStatic {
someMember(x: any): any;
//...
}
export interface SomeType { /***/ }
declare var $: JQueryStatic;
export default $; Second attemptI thought the following might work with // File: jquery.d.ts
declare namespace api {
export function someMember(x: any): any;
export interface SomeType { /***/ }
}
export = api; But I still get the following error when trying to augment this: // File: plugin.ts
declare module 'jquery' {
export function myPlugin(); // ERROR: cannot add top-level names
} I thought the idea behind #6742 was if the RHS of the |
closing in favor of #7125 |
Did you mean #7148? |
Also, AFAIK there is now no open issue tracking global augmentations, which you said was a desired feature in #7015 (comment) EDIT: I created an issue for it: #7161 |
I'm just curious about the rationale for the following aspect of the new module augmentation feature in v1.8:
I couldn't find any discussion about why this restriction exists. Is it technical? It is to direct people towards specific practices?
I ask because it seems to make it difficult to model existing JavaScript behaviour in some cases.
Example: A jQuery Plugin
With this restriction in place, what is the best way, for example, to write the type declaration for
plugin
, which adds itself as a top-level property of the object exported byjquery
? Assume AMD module loading. I tried a few approaches:Option 1
This is to me the most obvious and the simplest approach, but it is not allowed.
Option 2
This approach tries to augment an existing declaration to satisfy the augmentation rules.
Option 2 still doesn't work because
JQueryStatic
is not exported fromjquery
. There are also other problems with this approach:JQueryStatic
was exported (which makes this option work), the augmenter needs to study the 'internal' details ofjquery.d.ts
to find the right name to augment. This seems like an unnecessary detail, not to mention risky because the name might be changed in a futurejquery.d.ts
rearrangement.export
in front ofJQueryStatic
injquery.d.ts
doesn't work, because, like very many typings on DefinitelyTyped, it usesexport=
syntax which precludes other exports, so to exportJQueryStatic
would involve more extensive changes injquery.d.ts
.Option 3
This approach works, but doesn't use the new module augmentation feature at all. It relies on good old ambient declarations.
Option 3 also has problems:
plugin.d.ts
must remain purely ambient for this to work. Ifplugin
declares its own exports (e.g. exporting thePlugin
interface), thenplugin.d.ts
will be treated as its own module, and the augmentation ofJQueryStatic
fails because it's no longer the globalJQueryStatic
, but an unrelated local one. (And this error is cryptic enough to cause confusion - e.g. see Provide a way to augment global interfaces from external modules #4166, Extending the Function interface in the presence of an import statement #5944).I've used
jquery
as an example, but this also applies to global augmentations, and of course to other commonly augmented JavaScript libraries.The text was updated successfully, but these errors were encountered: