Repository navigation
Namespace keyword #2159
Description
Activity
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensus
on Feb 27, 2015 Is this a keyword change only? For example, would clodules still be supported? (clamespaces?)
DanielRosenwasser commented
on Feb 27, 2015 MemberMore actionsIt's an additional keyword that does the same thing. To the best of my understanding from current discussions,
modulewould be deprecated in favor ofnamespace."clamespaces", "funspaces", and other exciting possibilities of names are just a nice bonus. 😄
I like this suggestion.
We could make this change more potent by accompanying it with the
usekeyword.math.ts
namespace math { export function add(x, y) { ... } }
foo.ts
/// <reference path='math.ts' /> var num = math.add(0, 1); // Error: Unknown reference 'math' use namespace math; var num = math.add(0, 1); // okay var num = add(0, 1); // also okayThis shouldn't be a breaking change because the error is only raised when the
namespacekeyword is used to declare a "module".At the moment we are forced to keep our namespaces relatively flat in order to avoid problems with accessing deeply nested types:
var foo = foo.bar.baz.bazooka.add(10,3);
I strongly support this. The number of times I've had to explain is insane. Thanks!
👍
A crucial expectation for namespaces is to span multiple declarations.
namespace Colors { export var Red = 'red'; } namespace Colors { export var Green = 'green'; }Here both Red and Green are heavily implied to be in the same namespace, as opposed to the second one extending the first.
Obviously, in JS/TS namespaces/internal modules actually create closures instead, see arguing about it on issue #447. This closure (and potentially an actual behaviour logic) doesn't quite fit with what 'namespace' implies. 'Module' is actually better.
module Colors { console.log('some work here...'); export var Red = 'red'; } module Colors { console.log('some other work here...'); export var Green = 'green'; }However 'module' can become confusing after ES6 gains wider adoption. How about 'namespace module' instead?
namespace module Colors { console.log('some work here...'); export var Red = 'red'; }That way it looks clearer to me. It still is havily hinting towards 'namespace modules' having behaviour, not just scope. But at the same time it's also clear those are some special modules, not your normal ES6 modules.
sophiajt commented
on Mar 3, 2015 ContributorAuthorMore actionsmihailik Not sure exactly what you mean. Multiple namespaces would let you span multiple declarations, just as internal modules do today. The codegen extends the existing module if it's there, rather than create a new closure each time. The linked issue seems to be more about the codegen being suboptimal in some cases.
Unlike modules, which are based around a file and aren't extendable, namespaces (nee internal modules) are extendable. The only caveat is that closed-over non-exported symbols can't be seen across each namespace being merged, but I'd argue that's a good thing rather than a bad thing.
Jon (@jbondc) external modules are called "Modules" in ECMAScript 6, so it makes sense to stick with calling them "Modules" in TypeScript.
jonathandturner the question is not whether it's a good or bad thing -- the question is whether it's a naturally expected thing.
I'd say that 'namespace' suggests it's a syntactic construct, whereas 'module' suggests lifetime and behaviour.
The objections to using
namespaceas the keyword seem rather academic from my point of view."clamespaces", "funspaces", and other exciting possibilities of names are just a nice bonus.
I support this simply because of the possibility of funspaces.
Great summary, Jon (@jbondc) !
To me keeping 'module', but adding a qualifier makes most sense: clearer English, and greater backward and forward compatibility. Few more:
scope module Colors { export var Red = 'red8'; } closure module Colors { export var Red = 'red9'; } extend module Colors { export var Red = 'red10'; }
Beware the familiarity of 'namespace' appealing to C#-aware folks! That's not a wise move to gain a wider foothold in JS universe.
I'm not quite following the arguments. So we don't want to introduce a new keyword, and we don't want to do C#-aware stuff, but nobody complained about
async/await?!4 remaining items
OK, but Java does not have a namespace keyword in the first place.
The crucial problem with using 'namespace' is that it already HAS a very specific meaning in languages like C# and C++. It specifically is a name space, a space for names. It's a naming/addressing thing -- not a behaviour thing.
Internal modules in TypeScript are emphatically not merely a naming tweak. Fundamentally those modules have lifetime and behaviour. Those are not just bolted-on aspects, the lifetime and behaviour of modules need to be actively managed. They cause their share of bugs, sometimes require careful re-ordering or renaming to ensure initialisers are executed correctly.
The difference between TS 'internal module' and C# 'namespace' is like a difference between Class and Record in Turbo Pascal, if you know what I mean ;-)
It does make sense to have a separate word for 'internal modules', but not necessarily a first borrowed idea from C# is the right one.
I dont see in my comment that I say JAVA do have "namespace" keyword. Just saying it in layman term for programmers that understand the concept of it.
If you would like the emit for namespaces to be different then that's just another suggestion. It doesn't really say anything about the need for wanting to have namespaces in TypeScript.
As long as the project overlords at Microsoft are content with the existing TS adoption, reusing the C# 'namespace' keyword is the reasonable way to go. Conquering the minds of the JS folk is not necessarily the goal, right? ;-)
I've read this interesting discussion. Both clever arguments on both side.
My opinion is the word "module" should stick to ES6 definition since TS has to be an ES6 superset.
And internal modules should be named in another way. The word "namespace" would be the most natural choice.It seems many agree that "external/internal modules" is now sub-optimal language and often confusing to explain. I would add that it's also confusing while coding, because the words
module,importandexportare overloaded. They function differently depending on which type of module you're coding.While I was learning TypeScript modules, I was initially under the impression that I could write an internal module, then simply add a compiler flag to magically produce an external module. It took time to realize things like:
- External modules should not contain a namespace (which is practically the raison d'être of internal modules).
- External modules do not contain the word
module. - The meaning and rules for
exportare different depending on the context. - It's very difficult to have one source file be usable as both a namespaced library (for browser) and an external module (for Node). I'm still trying to figure out a simple solution.
Overall, TypeScript's module terminology meant that, once I was comfortable with internal modules and started to create external modules, I had to "unlearn" assumptions I had made.
Re: the "namespace and C#" concern, I say this with love: the world does not revolve around C#.
Should we not use the termclassbecause it's so differently implemented in JavaScript?namespaceorpackageare the two best terms so far. It just so happens that both were clearly defined in ECMAScript 4.
[/me pours one out for ES4]In ES4,
packagewas the equivalent to a TypeScript internal module (though TS is more flexible).
An ES4namespacewas orthogonal to a package, and completely different from a C# namespace.http://www.ecma-international.org/activities/Languages/Language%20overview.pdf
Package definitions are global definitions, qualified by namespaces.
class, function, and var bindings in the package can be qualified by either an ordinary namespace value or one of the special namespaces internal and public, which are just aliases for the package-internal and package-public namespaces.package org.ecmascript.experiment { internal var v; } ... package org.ecmascript.experiment { public function f(k) { v += k; return v-1 } }ES4 namespaces always seemed a bit esoteric. I'd say few AS3/Tamarin developers ever made their own namespaces, whereas everyone created packages.
Explanations of ES4 namespaces:
http://blog.gskinner.com/archives/2010/01/a_complete_guid.html
http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/namespaces.htmlThat being said, ES4's definitions of
packageandnamespacehave no moral claim on us today. What have the dead to do with the living?Closed in #2923.
- addedCommittedThe team has roadmapped this issueThe team has roadmapped this issueand removedIn DiscussionNot yet reached consensusNot yet reached consensus
on Apr 29, 2015 - added a commit that references this issue
on Aug 10, 2015 - locked and limited conversation to collaborators
on Jun 18, 2018
Now that we have ES6 modules in TypeScript, we should probably move towards a cleaner separation in the module types.
In truth, "internal modules" have been a bit of confusion for developers new to TypeScript. They're much closer to what most people would call a namespace.
Likewise, "external modules" in JS speak really just are modules now.
Let's move to a simpler explanation and have namespaces and modules be more separate. We'd still support the previous syntax, but this would mean introducing a new keyword called 'namespace' that was a bit easier to read and doesn't conflict with ES6 terminology.
Before:
After: