26

Im authoring a TS library, and would like to export an instance of a class, I intend for it be used as singleton in the consuming application.

Right now I have the following structure:

index.ts

export { Foo } from './my-class';

foo.ts

export class Foo {
  functionA() {}
}

I'm then building into UMD format using webpack and babel, and in another application (Angular), I am able to import in my class, instantiate it and use it accordingly.

import { Foo } from 'foo';

private foo = new Foo();

const x = foo.functionA();

Is there a way to return an instantiated instance of my class or am I thinking about this the wrong way?

So instead of having to do new Foo(), the imported Foo would actually already be an instance?

Thanks

UPDATE I should have mentioned, I am exporting other things such as interfaces, so I don't think a default class export would be the right way to go correct? - see here

mindparse
  • 6,115
  • 27
  • 90
  • 191

4 Answers4

49

You can control what you're returning like so:

// Export the named class directly
export class Foo { }

// Export the named class indirectly
class Bar { }
export { Bar }

// Export an instance of the class directly
export const foo = new Foo();

// Export an instance of the class indirectly
const bar = new Bar();
export { bar };

Here's a TypeScript Playground link showing the code compiles and the produced javascript.

The TypeScript Handbook official documentation for exports (and imports, and re-exports): https://www.typescriptlang.org/docs/handbook/modules.html#export

The MDN documentation (courtesy of jo_va): https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export

And here's Basarat's guide for them: https://basarat.gitbooks.io/typescript/docs/project/modules.html

15

Yes this is totally possible, and this is a standard way to do it in TS too.

export default new Foo();

If however you want to import not only this instance but interfaces as well, you would export the singleton like this:

export const foo = new Foo();

You can find the export doc here

jo_va
  • 13,504
  • 3
  • 23
  • 47
  • Thanks, I have updated my question since I don't think a default export is what I want as I am exporting other things too such as interfaces – mindparse Jan 24 '19 at 16:56
7

If you want singleton only, you should stick to the singleton convention,

  export class Foo {
    private static _instance = new Foo();
    private constructor() {

    }

    static get instance() {
      return this._instance;
    }

  }

  export const foo = Foo.instance;
ABOS
  • 3,723
  • 3
  • 17
  • 23
  • 2
    Selected answer will work for singletons as well. Other languages principles doesn't necessarily fit in JavaScript. – RA. Jul 16 '19 at 00:14
  • I like this answer which demonstrate how to write a singleton in js. I had some issues when exporting instance (not singleton) and then `import` from multiple places causes the file to be executed multiple times (`console.log()` at top level in that file is run several times). – Shawn Feb 28 '20 at 01:17
  • There's also a visual studio magazine post on how to write singleton using private constructor in detail: https://visualstudiomagazine.com/articles/2016/12/01/defining-classes.aspx – Shawn Mar 08 '20 at 06:35
  • @ShaungCheng `import` should be cached after first import. If a console.log was added to the accepted answer you would only see it once. If you're seeing multiple console.logs that makes me think you are executing a factory function. – Alex Jul 31 '20 at 22:06
3

It is possible to export the instance of the class Members.

Export the class instance like this: export const playerRoutes = new Routes

Export the class like this: export class player