88

Is it possible to create a private "function" (method) within a TypeScript class? Let's assume we have the following Person.ts TypeScript file:

class Person {
    constructor(public firstName: string, public lastName: string) {
    }

    public shout(phrase: string) {
        alert(phrase);
    }

    private whisper(phrase: string) {
        console.log(phrase);
    }
}

Which when compiled is being transformed to the following:

var Person = (function () {
    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    Person.prototype.shout = function (phrase) {
        alert(phrase);
    };
    Person.prototype.whisper = function (phrase) {
        console.log(phrase);
    };
    return Person;
})();

Observations

I was expecting the whisper function to be declared within the closure, but not on the prototype? Essentially this makes the whisper function public when compiled?

Richard
  • 8,110
  • 3
  • 36
  • 59
  • 1
    possible duplicate of [TypeScript private members](http://stackoverflow.com/questions/12713659/typescript-private-members) – Jude Fisher Jun 04 '13 at 14:02

3 Answers3

99

Update. Private methods using # are now implemented. See here: https://github.com/microsoft/TypeScript/pull/42458

--

TypeScript public/private keywords only apply to the way TypeScript checks your code - they don't have any effect on the JavaScript output.

According to the language specification (pp. 9-10):

Private visibility is a design-time construct; it is enforced during static type checking but does not imply any runtime enforcement. ... TypeScript enforces encapsulation of implementation in classes at design time (by restricting use of private members), but cannot enforce encapsulation at runtime because all object properties are accessible at runtime. Future versions of JavaScript may provide private names which would enable runtime enforcement of private members

This has already been asked and answered here: https://stackoverflow.com/a/12713869/1014822

Update: This old answer still gets an amount of traffic, so worth noting that, in addition to the language spec link above, public, private, and (now) protected members are covered in detail in the TypeScript handbook chapter on classes.

2018 Update Implementation of ES Private Fields is now a Future item on the TypeScript RoadMap although discussion suggests this will be a parallel hard private option, not a replacement for the current soft private implementation.

2020 Update Runtime private fields using the # operator have been implemented as of TS 3.8. There is a good discussion of how they work and how they differ from compile-time fields with the private keyword on StackOverflow here.

Private methods have reached stage 3 of the TC39 working group. The feature is currently in active discussion for TypeScript, for example here.

Jude Fisher
  • 11,138
  • 7
  • 48
  • 91
11

In Javascript (as opposed to TypeScript), you can't have a private "member" function.

If you define a private function in the closure, you won't be able to call it as an instance method on an instance of your class.

If that's what you want, just move the TypeScript function definition outside the class body.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Hmm, I guess there where the `var self = this;` applies? Is it possible to declare a function within a closure that doesn't explicitly access any instance information? – Richard Jun 04 '13 at 13:49
  • 2
    @Richard: No; `var self = this` has nothing to do with this. The point is that there is no way to make `instance.method()` only work in your closure. – SLaks Jun 04 '13 at 13:51
  • Sure; but it is possible to simply call `method()` from within an instance (public) method, is it not? – Richard Jun 04 '13 at 13:53
  • 1
    Yes, but it will have nothing to do with the class. (although you can accept `this` as a parameter) – SLaks Jun 04 '13 at 13:54
  • It can be done, but every call to a private method would have to be done using apply() or call() with the instance "this". – nomæd Jan 19 '16 at 07:52
3

You can use private class variables and functions in TypeScript/Webpack and even in the latest Google Chrome versions natively. Just add a # before the name. See here.

MyClass {

  #privateMember: Number = 4 

  #privateMethod() {
      this.#privateMember = 3
  }
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
air5
  • 140
  • 2
  • 10