6uitar6reat6od 6uitar6reat6od - 2 months ago 42
TypeScript Question

TypeScript default constant export

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

Let the library be an npm package named

foo
, its main file works as 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 library class as well as a default instance for apps to use it without creating a new one unless necessary.

Also, we created the type definition files in a separate repository in a similar way to DefinitelyTyped:

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

const foo: Foo;

export default foo;
}

declare module 'foo' {
export = Foo;
}


Running the tests for it fails with
error TS1063: An export assignment cannot be used in a namespace.


What I'm aiming for is to have the usage of the default instance like this:

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

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

foo.someMethod();


Any ideas if there is a right way to do this?

EDIT

Declaring just the module as @daniel-rosenwasser suggested worked before, but there was a problem when we tried to create a new module that extended the first.

For instance:

// bar.d.ts
/// <reference path="../foo/foo.d.ts"/>

import {
Foo
} from 'foo';

declare module 'bar' {
export class Bar extends Foo {
public constructor();
// more methods
}
}


And its tests:

// bar-tests.ts
/// <reference path="../foo/foo.d.ts"/>
/// <reference path="./bar.d.ts"/>

import foo, {
Foo
} from 'foo';

import {
Bar
} from 'bar';

namespace TestBar {
{
let result: Foo;
result = foo;
}

{
let result: Foo;
result = new Bar();
}
}


The errors this time are:

bar/bar-tests.ts: error TS2307: Cannot find module 'bar'.
bar/bar.d.ts: error TS2664: Invalid module name in augmentation, module 'bar' cannot be found.

Answer

The error message here is wrong, so I opened up an issue for you: https://github.com/Microsoft/TypeScript/issues/11092

If you have an ES-style module, you should define it directly in the ambient module declaration:

declare module "foo" {
    export class Foo {
        public constructor()
        // ...methods
    }

    const foo: Foo;

    export default foo;
}
Comments