TypeScript default constant export

3

We have a TypeScript library that we are publishing to a private NPM environment and we want to use it in other projects whether they are in TS, ES6 or ES5.

Let's say that the library is a npm package called foo , whose main file works like a "barrel" doing the following:

// Index.ts
import Foo from './Core/Foo';

export {default as Foo} from './Core/Foo';

const foo = new Foo();

export default foo;

We want to export the main class of the library, as well as a default instance of it so that the applications use it without creating a new one, unless it is necessary.

In addition, we have created the definition files in a separate repository similar to DefinitelyTyped:

// foo.d.ts
namespace Foo {
  export class Foo {
    public constructor()
    // ...methods
  }

  const foo: Foo;

  export default foo;
}

module 'foo' {
  export = Foo;
}

Running the tests fails with:

  

TS1063 error: An export assignment can not be used in a namespace.

What we are looking for is to use the default instance as follows:

// ES5, browser env
window.Foo.foo.someMethod();

// ES6/TS
import foo from 'foo';

foo.someMethod();

Any ideas on how to do this correctly?

    
asked by RecuencoJones 23.09.2016 в 13:28
source

2 answers

1

Solved! Original Post in StackOverflow

The solution is to forget the namespace and leave everything as a module declaration:

// foo.d.ts
declare module 'foo' {
  export class Foo {
    public constructor();
    public method(): void;
  }

  const foo: Foo;

  export default foo;
}

And any module that is going to extend it, must make the imports within its module declaration:

// bar.d.ts
declare module 'bar' {
  import {
    Foo
  } from 'foo';

  export class Bar extends Foo {
    public constructor();
    public anotherMethod(): void;
  }
}
    
answered by 24.09.2016 / 11:35
source
1

When you are implementing the library in TypeScript it is not necessary to build the type definition files manually because you can take advantage of those generated by the TypeScript compilation process

For this you have to set the compile option "declaration": true in the file tsconfig.json and, when copying the project, the type definition files will be generated in the same compilation directory.

//archivo index.d.ts
import { Foo } from './Foo';
export { Foo } from './Foo';
export declare const foo: Foo;

//archivo Foo.d.ts
export class Foo {
    public constructor();
    public method(): void;
}

Also, if in the file package.json of your library you add the property "types" referring to the file index.d.ts the compilation process of typescript will know how to find the types of your library

//archivo package.json de la librería foo
{
  "name": "foo",
  "version": "1.0.0",
  "description": "",
  "main": "dist/foo.js",
  "types": "dist/types/index.d.ts",
  "author": "",
  "license": "ISC"
}

You can see an example of this type in this GitHub repository

  

Note: this works from TypeScript 2.0

Finally, there is also a project called dts-bundle with which you could generate a single file that brings together all the files .d.ts of your library (including the module definition)

    
answered by 25.09.2016 в 20:25