You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've sadly discovered that it not possible to augment a ES2015 module that is being re-exported. At least not without specifying the full path to the ES2015 that is then being re-exported.
This has significant implications, particularly for library authors and consumers.
An example would probably help clarify.
Suppose as an authored of a library I want to expose a simple surface area from which consumers should import from. I do this by creating an index.ts file that re-exports modules from nested sub-folders like so:
As library author I am free to reorganise the modules into sub-folders as the library code base grows without breaking consumers
As library consumer I don't need to have intimate knowledge of how the library organises it's file on disk - instead I have one path to import modules and this is the name of the npm package itself.
Once augmentation enters the picture all of the above benefits are now gone.
Also, not being able to augment a re-exported module can cause confusion (eg: #11406) but does not necessarily have an obvious solution as per Ryan Cavanaugh (@RyanCavanaugh)comment
so, is this your library? or a library you are using?
one thing to note, ES2015 does not allow augmenting on the top level of a module anyways. so moving forward the only augmentation allowed at runtime is augmenting export shapes themselves.
There was a similar discussion at #9532 (comment). The only workaround I'm aware of is to augment the specific module instead of the exported one but that has all the caveats you mentioned. E.g. declare module './path/to/class-a'.
Ah, this is why it's not working. I'm trying to do the same thing as Endel Dreyer (@endel) (augmenting a re-exported class from the package-scoped three module).
The OP is slightly ambiguous so I'll address both.
If the request is to allow the exporting library to create a new type that augments AClass, that's a strong "no" due to our current architecture and potential user confusion.
If the request is that augmentors can augment the exported AClass type as if it were declared upfront in the exporting library, 100% yes, that "should" work (where "should" is defined as "it is effectively feature work to support each possible variant, but we are on board with someone contributing that work"). Effectively, augmenting any type or value through its aliases should be the same as augmenting the type or value at its original declaration site.
Reacted by Ethan Resnick, Alexandre de Boutray, J-Rojas, Loris Leiva, Chris Haws, Gonçalo Tavares and Keal Jones
It is important to fix this issue because, as Christian Crowhurst (@christianacca) said, "the [library] author loses the freedom to rearrange modules inside a package". Notice also the inconsistency: for a consumer of a package, to use a re-exported type you just specify the package name and the type name:
import{Type}from"library"
To augment, however, you have to know where this type definition resides within the source tree of the library:
Very maddening bug... it should be documented at least somewhere the current limitation. I've wasted hours on this bug, finally found this issue to explain some of this.
Three.js is organized is such a way that augmentation will fail as others mentioned.
Activity
christianacca commentedon Dec 1, 2016
Also, not being able to augment a re-exported module can cause confusion (eg: #11406) but does not necessarily have an obvious solution as per Ryan Cavanaugh (@RyanCavanaugh) comment
mhegazy commentedon Dec 1, 2016
so, is this your library? or a library you are using?
one thing to note, ES2015 does not allow augmenting on the top level of a module anyways. so moving forward the only augmentation allowed at runtime is augmenting export shapes themselves.
christianacca commentedon Dec 1, 2016
Hi Mohamed Hegazy (@mhegazy) thanks for the quick reply.
Let's suppose this is a library I'm using that's been authored by someone else.
In reality, I hit this issue whilst writing a demo app of a library that I'm authoring. I spent 2 hours banging my head thinking I was going crazy!
In my case I was trying to augment an interface re-exported from ng-table
blakeembrey commentedon Dec 1, 2016
There was a similar discussion at #9532 (comment). The only workaround I'm aware of is to augment the specific module instead of the exported one but that has all the caveats you mentioned. E.g.
declare module './path/to/class-a'.christianacca commentedon Dec 1, 2016
Yup that is the workaround, but not a particularly satisfying one.
It means the author loses the freedom to rearrange modules inside a package. The consumer also has to know the "internal" paths.
doliver3 commentedon Feb 19, 2017
I've hit the same problem. It is important to have a solution to this problem.
endel commentedon Feb 25, 2018
I've just hit this problem too. I'd like to augment
THREEmodule but it's not possible.Tried many ways, without success, such as:
Any workaround for this would be appreciated!
the-reality-engineer commentedon Oct 9, 2018
Ah, this is why it's not working. I'm trying to do the same thing as Endel Dreyer (@endel) (augmenting a re-exported class from the package-scoped
threemodule).EDIT, this worked for me:
the-reality-engineer commentedon Feb 14, 2019
I keep running into this issue over again, forgetting that I can't augment re-exported modules. Would be great if this were fixed.
RyanCavanaugh commentedon Apr 1, 2019
The OP is slightly ambiguous so I'll address both.
If the request is to allow the exporting library to create a new type that augments
AClass, that's a strong "no" due to our current architecture and potential user confusion.If the request is that augmentors can augment the exported
AClasstype as if it were declared upfront in the exporting library, 100% yes, that "should" work (where "should" is defined as "it is effectively feature work to support each possible variant, but we are on board with someone contributing that work"). Effectively, augmenting any type or value through its aliases should be the same as augmenting the type or value at its original declaration site.zpdDG4gta8XKpMCd commentedon Apr 2, 2019
duplicate of #8545?
mmichlin66 commentedon Jun 15, 2019
It is important to fix this issue because, as Christian Crowhurst (@christianacca) said, "the [library] author loses the freedom to rearrange modules inside a package". Notice also the inconsistency: for a consumer of a package, to use a re-exported type you just specify the package name and the type name:
To augment, however, you have to know where this type definition resides within the source tree of the library:
J-Rojas commentedon Aug 31, 2021
Very maddening bug... it should be documented at least somewhere the current limitation. I've wasted hours on this bug, finally found this issue to explain some of this.
Three.js is organized is such a way that augmentation will fail as others mentioned.
avin-kavish commentedon Jun 23, 2022
Is this still happening?
I think as long as the declared module path and the import path are the same, it works now.
macarie commentedon Jul 28, 2022
No, I don't think this is working.
e.g. in https://github.com/pmndrs/valtio, the
useSnapshotfunction is exported in the index file from'./react', anddoes not augment the module, but overwrites it.
Is the above code correct? If it is, are there any known workarounds?
ref: pmndrs/valtio#458