镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Error while accessing Namespace level variables from multiple files defining the same namespace. #6457

Closed

Description

I have two files main.ts and secondfile.ts defining a namespace System.Parent.Level1Child

Below are the contents of main.ts

namespace System.Parent.Level1Child{
    var parameterToShareBetweenFiles: number = 0;
    export class ChildClass1{
        constructor(){
            parameterToShareBetweenFiles += 1;
        }
    }
}

Below are the contents of secondfile.ts

/// <reference path="main" />

namespace System.Parent.Level1Child{
    export class ChildClass2{
        constructor(){
            parameterToShareBetweenFiles += 1;
        }
    }   
}

Since I am extending the same namespace, I would expect that the parameterToShareBetweenFiles should be available in the secondfile.ts but the compiler throws

error TS2304: Cannot find name 'parameterToShareBetweenFiles'

I believe this is a Bug and needs to be fixed. Because the error doesn't come if the class definition for ChildClass2 is brought into the main.ts file as below. Does this mean that the entire namespace has to be defined in a single file? That is very inconvenient especially with multiple developers contributing to the same namespace.

namespace System.Parent.Level1Child{
    var parameterToShareBetweenFiles: number = 0;
    export class ChildClass1{
        constructor(){
            parameterToShareBetweenFiles += 1;
        }
    }
    export class ChildClass2{
        constructor(){
            parameterToShareBetweenFiles += 1;
        }
    }   
}

Activity

  1. mhegazy commented on Jan 12, 2016

    @mhegazy
    Contributor

    you need to export the variable to make it accessible across declarations.

    namespace System.Parent.Level1Child{
       export var parameterToShareBetweenFiles: number = 0;
    }
  2. seshualluvada commented on Jan 12, 2016

    @seshualluvada
    Author

    Thanks that works. The resulting javascript defines the namespace twice rather than optimizing the code into one block of code. Is this by design? This is not optimal.

    var System;
    (function (System) {
        var Parent;
        (function (Parent) {
            var Level1Child;
            (function (Level1Child) {
                Level1Child.parameterToShareBetweenFiles = 0;
                var ChildClass1 = (function () {
                    function ChildClass1() {
                        Level1Child.parameterToShareBetweenFiles += 1;
                    }
                    return ChildClass1;
                })();
                Level1Child.ChildClass1 = ChildClass1;
            })(Level1Child = Parent.Level1Child || (Parent.Level1Child = {}));
        })(Parent = System.Parent || (System.Parent = {}));
    })(System || (System = {}));
    var System;
    (function (System) {
        var Parent;
        (function (Parent) {
            var Level1Child;
            (function (Level1Child) {
                var ChildClass2 = (function () {
                    function ChildClass2() {
                        Level1Child.parameterToShareBetweenFiles += 1;
                    }
                    return ChildClass2;
                })();
                Level1Child.ChildClass2 = ChildClass2;
            })(Level1Child = Parent.Level1Child || (Parent.Level1Child = {}));
        })(Parent = System.Parent || (System.Parent = {}));
    })(System || (System = {}));
    
    
  3. mhegazy commented on Jan 12, 2016

    @mhegazy
    Contributor

    it is by design. there are scoping issues in place that warrants different closures. you can read more about this in #447

  4. seshualluvada commented on Jan 12, 2016

    @seshualluvada
    Author

    Thanks for referring the issue #447. The problem with exporting the internal variables in the namespace is that they are exposed to code outside the namespace. In my third file namespaceclient.ts, I see that I am able to access and manipulate the parameterToShareBetweenFiles. This variable wasn't supposed to be accessible this way but only to classes which are with in the namespace.

    Below are the contents of namespaceclient.ts

    /// <reference path="secondfile" />
    
    var classvar1  = new System.Parent.Level1Child.ChildClass1();
    //this variable was not supposed to be accessed like this but TypeScript is allowing.
    System.Parent.Level1Child.parameterToShareBetweenFiles += 1; 
    

    How can a developer protect the variables with in the namespace to be only accessible by code defined in the context of the namespace and not outside it?

  5. mhegazy commented on Jan 12, 2016

    @mhegazy
    Contributor

    TypeScript does not have an internal modifier (#5228) at the moment. keep in mind that namespaces are objects at the end of the day. and exported members are just properties on the object, so any one can access them.

  6. 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

Assignees

No one assigned

    Labels

    QuestionAn 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