Picci
Picci

Reputation: 17752

Typescript error "An export assignment cannot be used in a module with other exported elements." while extending typescript definitions

I have downloaded the type definition of a module, let's say ModuleA, from @types/module-a.

The module-a.d.ts file looks like

declare module "module-a" {
  export = moda;
}

declare namespace moda {
  interface MODAPromise<T> {
    isResolved(): boolean;
    ....;
  }
}

Now, in my application, I find that I need to extend these types with some additional specifications.

Following advice received earlier, I build in my src directory a file module-a.augmented.d.ts such at this

declare module "module-a" {
    export interface MODAPromise {
        myNewProperty: any;
    }
}

If I do so though, TypeScript signals an error "An export assignment cannot be used in a module with other exported elements." in line

export = moda;

of module-a.d.ts. Is there a way to extend such type of declaration without having to touch the original module-a.d.ts file?

Upvotes: 21

Views: 15519

Answers (2)

binki
binki

Reputation: 8308

I found that I could combine export = syntax with namespace to export types from the interface. export = is necessary (as far as I understand) to indicate that an external module uses CommonJS-style exports rather than ES6 exports. If you try to both use export = and export in the same module, you will receive the following error:

TS2309: An export assignment cannot be used in a module with other exported elements.

However, if you declare a declare a namespace with the same name as the variable used in the exports = expression, you can place types inside of that namespace, making them accessible to consuming modules.

Here is an example of a module type definition using this technique:

declare module 'some-module' {
  namespace SomeClass {
    export interface IMyInterface {
      x:string;
    };
  }
  class SomeClass {
    constructor(p:SomeClass.IMyInterface);
  }
  export = SomeClass;
}

Upvotes: 25

Amit Beckenstein
Amit Beckenstein

Reputation: 1332

That is because you set the export to namespace moda in "module-a" that is defined in module-a.d.ts, and also export MODAPromise in "module-a" that is defined in module-a.augmented.d.ts.

Therefore, the "module-a" you're attempting to define looks like this:

declare module "module-a" {
    export = moda;
    export interface MODAPromise {
        // ...
    }
}

You're attempting to set the export, and export something else at the same time, which makes no sense. You need to find another way to export moda's MODAPromise and the augmented MODAPromise in the same time.

Upvotes: 2

Related Questions