Reputation: 297
I have added following class in typescript
class Person {
private variable1;
public varibele2;
Person(){
this.variable1 = 'abc';
this.varibele2 = 'xyz';
}
public getVariable1(){
return this.variable1;
}
}
So When I compile the code using tsc , it generates the following code
var Person = (function () {
function Person() {
}
Person.prototype.Person = function () {
this.variable1 = 'abc';
this.varibele2 = 'xyz';
};
Person.prototype.getVariable1 = function () {
return this.variable1;
};
return Person;
}());
Since variable1 is private should not be accessible by the obj of that class(which is happening in typescript code).
Same behavior should be happened into transpiled es5 code(But not happening).
In above example's transpiled code I am creating object of the Person
var p = new Person();
console.log(p.variable1); // undefined
p.variable1 = 'abc1'; // setting value to variable 1
console.log(p.variable1); // 'abc1'
console.log(p.getVariable1()); // 'abc1'
In above code I should not be able to set or get the value of variable1.
var p = new Person();
console.log(p.getVariable1()); // 'undefined'
p.variable1 = 'abc1'; // setting value to variable1
console.log(p.getVariable1()); // 'abc1'
In above code , I am trying fetch the value using p.getVariable1() and I get undefined.Since value is already assigned in constructor of the class , it should be available through p.getVariable1()
var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'
In above code Variable2 should retrun 'xyz' but it's not. Once i assign value to it , it returns.
So Behavior of private and public variables are same in transpiled code and its very confusing. Its not returning the value which is assigned in constructor.
Upvotes: 4
Views: 2053
Reputation: 41
if the transpiled code is not using closure to make it private it means I can flout the variables when using it as a javascript library because I will never know what is private what is not. So the answer is transpiling the way typescript does is incorrect and not in true spirit of usage of javascript.
Upvotes: 1
Reputation: 3061
First, to respond to your main question:
Why private variable in a class is treated as public in the transpiled code.
It's true that private
properties, as well as readonly
properties, are transpiled into plain properties hence "public". I think it's to simplify and boost transpilation TS→JS and to favor using TypeScript everywhere, where warnings or errors are emitted when performing invalid operations on these kind of properties: accessing a private property outside the class, reassigning a readonly property...
But you give examples with very strange behaviors. They are not due to TypeScript transpilation. I notice some issues with your class Person that have led to them:
constructor
, not the class name. It's even more confusing because the constructor is transpiled into a function constructor named like the class, here Person
.varibele2
instead of variable2
. This is why console.log(p.variable2)
can't print the expected value.Fixing these issues, the code behaves more logically.
class Person {
constructor(private _variable1 = 'abc', public variable2 = 'xyz') { }
public get variable1() { return this._variable1; }
}
console.log(new Person()); // → Person { v1: [Getter], v2: "xyz", _v1: "abc", __proto__... }
The transpiled code is available through the TypeScript playground.
Note: I favor another syntax:
_x
to ease writing a getter get x() { return this._x; }
. It's also a commonly used JavaScript convention to indicate that the variable is meant to be private, without a complex pattern to really have a private property.Upvotes: 2
Reputation: 297
In following case as per my understanding, variable2 comes undefined because object p don't contain that variable.
In following code we are including variable using p.variable2 = 'xyz1' into object p. so in the third line we get the value of that variable.
var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'
Still the question is since typescript has declared the variable then why javascript(compiled code) object doesn't contain those variables?
Upvotes: 0
Reputation: 84982
To continue our discussion from the comments, here's the benefit that you get from using public vs private:
The IDE will tell you immediately that you're doing something you're not supposed to do. If you ignore these errors, the code will compile to javascript and run, but the point is that you don't ignore these errors. When you write bad code like this, typescript tells you there's a problem, and then you can fix the problem. If you have a build process, you can set it up so that these typescript errors will fail the build, thus forcing you to fix the problem before deploying.
Typescript is a tool to help you write better javascript code, by catching errors earlier and easier. It is not a tool to change the way javascript works. Typescript does not provide runtime type checking, and if that's what you're after, you won't find it. If you need closures to hide variables, then create a closure yourself.
Upvotes: 3