153

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{..}
}

2 Answers 2

196

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.

4
  • 1
    Thanks for the information, I assume that the decision was as you say to avoid having to check the context of the keyword, which is a shame as it feels like its something that will trip a few people up and really has no logical difference in behaviour to how you expect public to act, just makes their implementaiton easier.
    – Grofit
    Commented Apr 2, 2013 at 10:28
  • 1
    It is necessary if you are using modules. If you app is toward the larger side, modules are typically a better choice than creating big bundles / loading all your files up front.
    – Fenton
    Commented May 20, 2019 at 8:16
  • @Fenton Didn't you mean "you could argue that they should have used 'public' instead of 'export' ? Commented Mar 4, 2020 at 20:33
  • @AlanEvangelista you could certainly argue it that way round as well, especially if your background was Java / C# rather than JavaScript.
    – Fenton
    Commented Mar 9, 2020 at 14:25
54

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 adding public/private
  • It's definitely not to make the implementation easier; the added complexity of public vs export 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??), so private is the logical choice. Once you have private, it would be somewhat insane to not choose public as its counterpart
  • Use of export to modify visibility in internal modules is the best-guess alignment with ES6 modules
7
  • 1
    thanks for the additional information, I completely agree with the public/private being at member level, I just found it odd not to be sufficient for all levels of access. However this is a personal opinion and a keyword is a keyword, just wanted to find out more.
    – Grofit
    Commented Apr 2, 2013 at 16:41
  • I am confused by the first bullet point. Who is suggesting that export should have a third meaning? Commented Jun 18, 2015 at 19:37
  • 2
    I agree with some of what you're saying but I disagree with the statement "There isn't a suitable antonym to export" - "import" is the antonym, and is what TypeScript uses, when you define an exportable class, you then import it into other files export class User { name: string } Another file: import {User} from ""./the_file_path_to_the_user_class; see section 3.3 of the nativescript docs here docs.nativescript.org/angular/tutorial/ng-chapter-3 Commented Jun 6, 2016 at 14:13
  • 3
    How would using import to indicate "this value is not exported" be a suitable use of the keyword? Commented Jun 6, 2016 at 14:19
  • 8
    "There isn't a suitable antonym to export (unexport??)" - a suitable antonym for export should be embargo.
    – rsp
    Commented May 21, 2018 at 19:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.