Skip to content
New issue

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

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

Already on GitHub? # to your account

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

Closed
seshualluvada opened this issue Jan 12, 2016 · 5 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@seshualluvada
Copy link

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;
        }
    }   
}
@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Jan 12, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Jan 12, 2016

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

namespace System.Parent.Level1Child{
   export var parameterToShareBetweenFiles: number = 0;
}

@mhegazy mhegazy closed this as completed Jan 12, 2016
@seshualluvada
Copy link
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 = {}));

@mhegazy
Copy link
Contributor

mhegazy commented Jan 12, 2016

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

@seshualluvada
Copy link
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?

@mhegazy
Copy link
Contributor

mhegazy commented Jan 12, 2016

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.

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

No branches or pull requests

2 participants