Why does Typescript use the keyword "export" to make classes and interfaces public?
While dabbling with Typescript I realised my classes within modules (used as namespaces) were not available to other classes unless I wrote the export
keyword before them, such as:
module some.namespace.here
{
export class SomeClass{..}
}
So now I can use the above code like this:
var someVar = new some.namespace.here.SomeClass();
However I was just wondering why this keyword is used opposed to just using the public
keyword which is used at method level to signify that a method or property should be externally accessible. So why not just use this same mechanism to make classes and interfaces etc externally visible?
This would give resulting code like:
module some.namespace.here
{
public class SomeClass{..}
}
The primary reason is that export
matches the plans for ECMAScript. You could argue that "they should have used "export" instead of "public", but asides from "export/private/protected" being a poorly matched set of access modifiers, I believe there is a subtle difference between the two that explains this.
In TypeScript, marking a class member as public
or private
has no effect on the generated JavaScript. It is simply a design / compile time tool that you can use to stop your TypeScript code accessing things it shouldn't.
With the export
keyword, the JavaScript adds a line to add the exported item to the module. In your example: here.SomeClass = SomeClass;
.
So conceptually, visibility as controlled by public
and private
is just for tooling, whereas the export
keyword changes the output.
A few things to add to Steve Fenton's answer:
-
export
already means two different things (depending on whether it's at top-level or not); making it mean a third is probably worse than addingpublic
/private
- It's definitely not to make the implementation easier; the added complexity of
public
vsexport
is trivial. We've changed keywords around a bunch already; it's not difficult. - The default visibility of class members must be public to align with the ES6 class proposal, therefore we need some keyword to indicate "not public". There isn't a suitable antonym to
export
(unexport
??), soprivate
is the logical choice. Once you haveprivate
, it would be somewhat insane to not choosepublic
as its counterpart - Use of
export
to modify visibility in internal modules is the best-guess alignment with ES6 modules