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

Augmenting external module that is re-exported? #18877

Open
chriseppstein opened this issue Oct 1, 2017 · 5 comments
Open

Augmenting external module that is re-exported? #18877

chriseppstein opened this issue Oct 1, 2017 · 5 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@chriseppstein
Copy link

TypeScript Version: 2.5.2

Code

This can't be demonstrated with a simple 1-file code example so I made a trivial project to demo it:
https://github.com/chriseppstein/typescript_module_augmentation_bug

Instructions for how to run the demo and work around the issue are included on the README there.

When I include an interface in a node module's main index.ts file, then it is open for merging with a declare module "my_npm_module" {} but when I move that interface into a local submodule and export it in the main index.ts with a export * from "./local_module"; then the downstream consumer breaks.

Expected behavior:

It seems to me that the point of being able to export from other modules is to keep downstream consumers protected from internal refactors and maintain an existing public API. So I expect to be able to augment an interface and have it behave the same whether or not it has been re-exported.

Actual behavior:

It looks like the interface gets forked into two definitions, the downstream module sees only the interface surface that was added and the upstream module only sees the interface surface it defined.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 1, 2017

This is a known limitation. See #9532 and its cross-referencing issues for more details.

The only workaround is to augment the module that directly exports the declaration which of course presents maintainability problems and diminishes the level of abstraction. I've run into this a number of times. I usually just take the risk, targeting the module directly in the augmentation, knowing it may well break in the future.

@chriseppstein
Copy link
Author

@aluanhaddad Thanks for the reply. I've moved the code that needs to be augmented to the root of the node module. Not ideal, to say the least.

@mhegazy mhegazy added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Oct 4, 2017
Gerrit0 added a commit to TypeStrong/typedoc that referenced this issue Jan 2, 2019
@ktutnik
Copy link

ktutnik commented Mar 27, 2019

Look like this is bug in TypeScript 3.3.3333 I found that when using export star will cause augmentation failed. Workaround is manually export like below

export  { ClassA, ClassB, otherInstance, otherNamespace } from "my-cool-module"

@AnyhowStep
Copy link
Contributor

@ktutnik Thanks for the solid workaround.

I've moved all my "augmentable" types to a file called augmentable.ts.

Then, in index.ts,

export {
  TypeA,
  TypeB,
  TypeC,
  //snip
} from "./augmentable";

All other types (generics, functions, etc) that rely on declaration merging/augmentation import from augmentable.ts.

It seems to work well so far.

dunqan added a commit to SAP/spartacus that referenced this issue Aug 11, 2020
Allowing for the extensibility of our build-in core models helps in implementing a da- ta-driven approach for both our own libraries and 3rd party ones.

As there are some well-known limitations in TypeScript around it, mentioned in those tickets:

microsoft/TypeScript#9532
microsoft/TypeScript#18877
Spartacus uses additional build step for our libraries that will move augmentable models to main entry point generated by ng-packagr (eg spartacus-core.d.ts for core).

Closes #7940
ChumpChief added a commit to microsoft/FluidFramework that referenced this issue Feb 5, 2021
…ue (#5056)

When downstream customers augment the IRequestHeader, the [index: string]: any; signature is lost and they end up with "property does not exist" errors.

This change uses this workaround to resolve the issue:
microsoft/TypeScript#18877 (comment)
ChumpChief added a commit to ChumpChief/FluidFramework that referenced this issue Feb 5, 2021
…ue (microsoft#5056)

When downstream customers augment the IRequestHeader, the [index: string]: any; signature is lost and they end up with "property does not exist" errors.

This change uses this workaround to resolve the issue:
microsoft/TypeScript#18877 (comment)
ChumpChief added a commit to microsoft/FluidFramework that referenced this issue Feb 6, 2021
…ue (#5056) (#5063)

When downstream customers augment the IRequestHeader, the [index: string]: any; signature is lost and they end up with "property does not exist" errors.

This change uses this workaround to resolve the issue:
microsoft/TypeScript#18877 (comment)
function2-llx pushed a commit to function2-llx/zhengdianbaoshi_bot that referenced this issue May 3, 2021
@LucaCorcella
Copy link

Hi, I think this is not a problem. If you need to extend or augment a third-party library module in one or more submodules of your project, you need to add a declaration in the .d.ts file, this file will import your declaration into each module of your app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants