Search code examples
javascripttypescript2.0transpiler

How typescript internally handles encapsulation, inheritance and data hiding?


I am curious to explore and understand the typescript to es5 transpilation process. I am pretty clear on the part how typescript uses closures to create scopes and managing inheritance, what still surprises me on the fact that how exactly typescript implements private data members and encapsulation as in the compiled ES5, I don't see any difference between the private and public data member scope. How exactly typescripts handles privacy internally? What exactly is it doing for prototype inheritance (var __extends)?

Here is the link to the typescript playground, I am experimenting on: https://www.typescriptlang.org/play/#src=class%20Shape%7B%0D%0A%20%20%20%20private%20name%3A%20string%3B%0D%0A%20%20%20%20public%20shapeType%3A%20string%3B%0D%0A%0D%0A%20%20%20%20constructor(name%20%2C%20shapeType)%20%7B%0D%0A%20%20%20%20%20%20%20%20this.name%20%3D%20name%3B%0D%0A%20%20%20%20%20%20%20%20this.shapeType%20%3D%20shapeType%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20%0D%0A%7D%0D%0A%0D%0Aclass%20Triangle%20extends%20Shape%7B%0D%0A%20%20%20%20constructor(name%2C%20shapeType)%20%7B%0D%0A%20%20%20%20%20%20%20%20super(name%20%2C%20shapeType)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D

Typescript:

class Shape{
    private name: string;
    public shapeType: string;

    constructor(name , shapeType) {
        this.name = name;
        this.shapeType = shapeType;
    }

}

class Triangle extends Shape{
    constructor(name, shapeType) {
        super(name , shapeType);
    }
}

Transpiled JS:

var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Shape = /** @class */ (function () {
    function Shape(name, shapeType) {
        this.name = name;
        this.shapeType = shapeType;
    }
    return Shape;
}());
var Triangle = /** @class */ (function (_super) {
    __extends(Triangle, _super);
    function Triangle(name, shapeType) {
        return _super.call(this, name, shapeType) || this;
    }
    return Triangle;
}(Shape));

Solution

  • The privacy of members are only enforced within typescript itself. So they are "private" only in typescript for convinience. While in typescript the compiler just checks if the property is private but once transpiled a private property is a just regular property.

    If you are interested in making something private in JS, you can refer to Emulating private methods with closures