Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

typescript

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?

like image 208
Picci Avatar asked Feb 09 '18 14:02

Picci


2 Answers

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;
}
like image 139
binki Avatar answered Nov 19 '22 03:11

binki


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.

like image 2
Amit Beckenstein Avatar answered Nov 19 '22 05:11

Amit Beckenstein