Skip to content

Using "import" makes my namespace/module unavailable in other classes.  #8004

Closed

Description

I have 2 TypeScript modules like below. In the second module when I import a module, the classes, modules in the same namespace won't be accessible ( seems they don't exist ).

MyName.Modules.ts:

module MyName.Modules{
    export class Class1 {
        Name:string;
    }
}

MyName.Modules.Extras.ts:

/// <reference path="MyName.Modules.ts"/>
/// <reference path="nunjucks.d.ts"/>

/* if I comment this line of code MyName.Modules.Class1 is available
and if I won't do it TypeScript compiler can't find it.
*/
import * as nunjucks from "nunjucks";

module MyName.Modules.Extas{
    export class Class2 extends MyName.Modules.Class1 {
        public DoNothing():void{

        }
    }
}

P.S: nunjucks.d.ts is just an example, It doesn't matter what you import ...

Activity

  1. al1b commented on Apr 11, 2016

    @al1b
    Author

    Isn't it related to the rule below?

    Red Flags: https://www.typescriptlang.org/docs/handbook/modules.html
    Multiple files that have the same export namespace Foo { at top-level (don’t think that these are going to combine into one Foo!)

  2. aluanhaddad commented on Apr 11, 2016

    @aluanhaddad
    Contributor

    When a file begins with a top level import or export statement, it represents an external module. This means that all of its exports must be imported explicitly. The first module you have written is what has been called an internal module or a namespace (the dedicated namespace keyword is now available and should be used to disambiguate internal vs external modules).

    Anyway, I recommend something like

    MyName/Modules/Core.ts:

    export class Class1 {
        Name:string;
    }

    MyName/Modules/Extras.ts:

    import * as nunjucks from "nunjucks";
    import { Class1 } from "./Core";
    
    export class Class2 extends Class1 {
        public DoNothing(): void {
        }
    }

    You will need to set the compilerOptions.module property in your IDE/tsconfig.json.

    EDIT: correct paths and formatting

  3. RyanCavanaugh commented on Apr 11, 2016

    @RyanCavanaugh
    Member

    Need to add this to the FAQ.

  4. al1b commented on Apr 12, 2016

    @al1b
    Author

    Aluan Haddad (@aluanhaddad) Thanks. It'll solve my problem.

    P.S:
    Yesterday I read TypeScript handbook but I didn't find you mentioned.

  5. mhegazy commented on Apr 12, 2016

    @mhegazy
    Contributor
  6. MoonStorm commented on Jun 2, 2016

    @MoonStorm

    This needs to be re-designed. If later on an import is required into a file that originally had no imports, that would create a ripple effect throughout the entire code base.

  7. mhegazy commented on Jun 2, 2016

    @mhegazy
    Contributor

    use --module none if you do not intend to use modules, this way you will get an error once you have a top-level import or export.

  8. MoonStorm commented on Jun 2, 2016

    @MoonStorm

    Didn't say I don't intend to use modules. The simple fact that an import extracts that particular file out of its original scope and isolates it into a module, without even bringing the original namespace originally spaced out across multiple files with it, is simply a cop-out design for this feature.

    Correct me if I'm wrong, but from that point onwards every single file would need an import referencing the original, not to mention that now the other files now become modules as well. The whole namespace gets destroyed.

  9. RyanCavanaugh commented on Jun 2, 2016

    @RyanCavanaugh
    Member

    If you're using a module loader, everything you do is already in its own scope.

    It's not constructive to call it a "cop out" to accurately model the behavior of an existing system. What code would you propose we emit for an AMD-targeting program?

  10. MoonStorm commented on Jun 2, 2016

    @MoonStorm

    The namespace should remain intact, that's all I'm saying. I don't see any reason why it shouldn't. The isolation is now performed very rudimentary on files, instead of intelligently being done on logical groupings.

  11. aluanhaddad commented on Jun 2, 2016

    @aluanhaddad
    Contributor

    MoonStorm I sympathize with your feelings regarding modules, but this is not a failure on the part of the TypeScript team, it is rather a direct consequence of the module specification.
    The ECMAScript module specification defines physical modules not logical ones. While this has certain advantages, it's arguably a lower level of abstraction than what could be achieved through a logical module format. However by deviating from the specification, TypeScript would set itself up for long-term compatibility concerns.

  12. MoonStorm commented on Jun 2, 2016

    @MoonStorm

    Thanks for that Aluan Haddad (@aluanhaddad) . The situation is much more clear now.

    So what's the solution then? Keep everything in one TS file? Have one module per TS file? No thank you. It seems that the only common sense proposition for medium to large scale projects would be to code in a module-less manner and mash everything up at build time, however in this case the entire module support in Typescript can be thrown out the window. What is the general consensus on the matter?

  13. mhegazy commented on Sep 20, 2016

    @mhegazy
    Contributor

    The recommendation would be to code in modules and use a module bundler, like webpack, browserify or r.js for your output.

  14. aluanhaddad commented on Nov 1, 2016

    @aluanhaddad
    Contributor

    MoonStorm the general consensus is to go ahead and use ES Modules, and to explicitly import every construct from every file where needed. Something many use is an organizational convention where groups of modules, that is files, are re-exported by a co-located file generally named index.ts. Often this file itself is dozens of lines long.

    That said, if namespaces are working well for you, you can keep using them and you can still work with modular libraries via UMD style declarations and UMD bundles.

    That said moving to ES Modules is a good idea because that's where everything seems to be headed and the support will be there.

  15. brphelps commented on Nov 23, 2016

    @brphelps

    Thought I'd chime in here, because it was just last week that I was complaining about this.

    It is super unintuitive to go from using namespaces to using file modules. There's something inherently jarring about having individual files "knowing" about other individual files, physically (without additional work). I think the disappointment as far as being a TypeScript consumer goes is that there wasn't some whizbang magic solution that preserved the behavior of namespaces in TS files and completely hid the notion that one potential implementation of a namespaced system is by using window level globals.

    From my POV, TS should be smart enough to allow the conveniences of namespace syntax while still, behind the scenes, following modern module loading patterns. The fact that it doesn't makes me think that there should be big red tape everywhere we mention using namespaces saying "Absolutely do not do this, you will regret it in 1-12 months".

  16. mhegazy commented on Nov 24, 2016

    @mhegazy
    Contributor

    What we have seen working with teams to migrate to modules that most of the time is about the logic and figuring out what is your dependency tree, more than actually switching to the module syntax/module loader.

    when using namespace, all your code is in one place, and you have everything can access everything, once the initial load is done.

    once you move to modules you need to answer the question, what is a module, what components can be loaded by themselves, and what components can not exist without another, and thus should be loaded together.
    Sadly these are not things that the compiler can just know. it does not know if all declarations in a file should transition to a module because they are logical entity that need to live together, or they were placed in this file because it was convenient when this code was written. it does not know if a namespace should be split into two or modules, because the original design did not account for different load times or not.

    The main source of frustration is that modules and namespaces are eerily similar in syntax to modules, yet they are completely different beasts; developers usually think the transition between these two constructs can not be that big, yet it is.

  17. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

DocsThe issue relates to how you learn TypeScriptQuestionAn issue which isn't directly actionable in code

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions