Typescript: Re-export class from namespace

Created on 28 Aug 2015  路  10Comments  路  Source: microsoft/TypeScript

I want to re-export some class defined in a module scope from a nested namespace. First I tried new ES6 syntax, but got an error:

export class Foo {}
export namespace a {
    export { Foo } // TS1194: Export declarations are not permitted in a namespace.
}

袨泻, tried export import:

export class Foo {}
export namespace a {
    export import Foo = Foo; // TS2303: Circular definition of import alias 'Foo'.
}

So I have to define temporary import:

export class Foo {}
import FooTemp = Foo; // TS2503: Cannot find namespace 'Foo'.

Ok, let's declare module Foo also:

export class Foo {}
export module Foo {}
import FooTemp = Foo;
export namespace a {
    export import Foo = FooTemp;
}

And only now the compilation is successful. It's really complicated workaround. And it forces to define extra variable in generated JS. I would prefer the first or second code sample. Or maybe is there another way?

Question

Most helpful comment

@mhegazy anything come out of this? if so could you link from here, as I landed here via google search. Thanks.

All 10 comments

I found better workaround - rename the source class:

class FooTemp {}
module FooTemp {}
export { FooTemp as Foo }
export namespace a {
    export import Foo = FooTemp;
}

It's also complicated but there is no extra variable in JS.

There's not much we can do here since, at runtime, the name Foo only has one meaning inside a.

@RyanCavanaugh Why ES6 export declarations are not supported in namespaces? In the generated JS code this can look like this:

    var Foo = (function () {
        function Foo() {
        }
        return Foo;
    })();
    exports.Foo = Foo;
    var a;
    (function (a) {
        a.Foo = Foo;
    })(a = exports.a || (exports.a = {}));

This works fine at runtime.

And why do I have to declare module/namespace Foo to import class Foo?

And why do I have to declare module/namespace Foo to import class Foo?

There is no reason really. we wanted to limit the use of imports to avoid conflicts with ES6 syntax. i think we should reconsider. @Koloto would you mind filing a suggestion for it.

@mhegazy anything come out of this? if so could you link from here, as I landed here via google search. Thanks.

no issue tracking this.

I got here from a desperate search too. It appears to still be broken? Any new word?

Please make it append. Non intuitive workaround can lead to bad practices.

import Class1 from "./Class1";
import Class2 from "./Class2";
import {Class3, Class4} from "./OtherClasses1";
import {Class5, Class6} from "./OtherClasses2";

export {Class1, Class2} //ok

export namespace OtherClasses {
    export {Class3, Class4, Class5, Class6}; // export not permitted...
}
// or better
export {Class3, Class4, Class5, Class6} as OtherClasses; // not working nether obviously.

// -- This workaround works, but it's sad to use it like this...
export const OtherClasses = {
    Class3: Class3,
    Class4: Class4,
    Class5: Class5,
    Class6: Class6,
};

@bios21 does TS let you define variables in other modules?
var someVar: rootModule.OtherClasses.Class3;
I cannot get it to work in my project - TS complains "TS2305: Module 'rootModule' has no exported member 'OtherClasses'" although the following line is compiled
console.log(rootModule.OtherClasses.Class3);

@MaximBalaganskiy I have no problem with this line.
Dummy code for example:

// MyModule.ts
export default class Sub {} // (Sub ~= Class3 in your snippet)
// index.ts (my entry point in webpack context)
// all exports are bundled into the rootModule object
import Sub from './MyModule';

export const NS = { //in this fake namespace, it's !object! not type description (NS ~= OtherClasses in your snippet)
    Sub: Sub // can be 'AnyOtherVarName: Sub' ; Sub type is invariant in this case except if you 'import-as' it.
}
// in any other external ts file
import * as rootModule from 'the-module-bundled';
import {NS} from 'the-module-bundled';
var someVar: rootModule.NS.Sub; // ok
var someOtherVar = new rootModule.NS.Sub(); // ok
var someVarAgain: NS.Sub; // ok
var someOtherVarAgain = new NS.Sub(); // ok
Was this page helpful?
0 / 5 - 0 ratings

Related issues

siddjain picture siddjain  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

jbondc picture jbondc  路  3Comments

uber5001 picture uber5001  路  3Comments

remojansen picture remojansen  路  3Comments