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?
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
Most helpful comment
@mhegazy anything come out of this? if so could you link from here, as I landed here via google search. Thanks.