Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-export class from namespace #4529

Closed
Koloto opened this issue Aug 28, 2015 · 10 comments
Closed

Re-export class from namespace #4529

Koloto opened this issue Aug 28, 2015 · 10 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@Koloto
Copy link

Koloto commented Aug 28, 2015

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?

@Koloto
Copy link
Author

Koloto commented Aug 28, 2015

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.

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Aug 28, 2015
@RyanCavanaugh
Copy link
Member

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

@Koloto
Copy link
Author

Koloto commented Aug 29, 2015

@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?

@mhegazy
Copy link
Contributor

mhegazy commented Sep 17, 2015

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 mhegazy closed this as completed Sep 17, 2015
@rybolt
Copy link

rybolt commented Jul 8, 2016

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

@mhegazy
Copy link
Contributor

mhegazy commented Jul 8, 2016

no issue tracking this.

@robey
Copy link

robey commented Jan 23, 2017

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

@lsagetlethias
Copy link

lsagetlethias commented Feb 3, 2017

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,
};

@MaximBalaganskiy
Copy link

MaximBalaganskiy commented Feb 20, 2017

@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);

@lsagetlethias
Copy link

lsagetlethias commented Feb 20, 2017

@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

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

7 participants