2

In Javascript I can create a property of object with get/set methods :

function Field(arg){
    var value = arg;

    // Create a read only property "name"
    Object.defineProperty(this, "value", {           
        get: function () {
            return value;
        },
        set: function () {
            console.log("cannot set");
        }
    });
}

var obj = new Field(10);    
console.log(obj.value); // 10
obj.value = 20;         // "cannot set"

Setting value property is disallowed here.

In TypeScript if I want to achieve the same behaviour I would have to do this (as suggested by get and set in TypeScript):

class Field {
    _value: number;

    constructor(arg) {
        this._value = arg;
    }

    get value() {
        return this._value;
    }

    set value() {
        console.log("cannot set");
    }
}

var obj = new Field(10);

console.log(obj.value); // 10
obj.value = 20;         // "cannot set"
obj._value = 20;        // ABLE TO CHANGE THE VALUE !
console.log(obj.value); // 20

But the problem as you see here is that the so-called private property _value can be accessed/changed by the user directly without going through get/set methods for value. How do I restrict the user from accessing this property (_value) directly?

Community
  • 1
  • 1
FacePalm
  • 10,992
  • 5
  • 48
  • 50

4 Answers4

4

You can use Object.defineProperty in TypeScript as well.

I've modified your Field class like:

class Field{
    value: any;
    constructor(arg: any)
    {
        var value = arg;
        Object.defineProperty(this, "value",{           
            get: () => {
                return value;
            },
            set: function () {
                console.log("cannot set");
            }
        });
    }
}

Note that you cannot use the value defined on the class itself, otherwise the getter of the field would be recursively called until you'd run into a Maximum call stack size exceeded. The value:any declaration on the class definition avoids the compiler error:

the property "value" does not exist on value of type Field

You can then execute this TypeScript code to get the same results as your JavaScript code example:

var obj = new Field(10);
console.log(obj.value);
obj.value = 20;
thomaux
  • 19,133
  • 10
  • 76
  • 103
1

Within TypeScript it should be as simple as adding the private modifier (in your example, _value is public):

private _value:number;

... the compiler should now prevent you from setting the property from outside the class:

var obj = new Field(10);
obj._value = 20; // Error: The property '_value' does not exist on value of type 'Field'.

But this doesn't hide _value in the same way in the output JS. TypeScript private members are private only within TS. See this answer and the interesting codeplex discussion it links to.

Community
  • 1
  • 1
Jude Fisher
  • 11,138
  • 7
  • 48
  • 91
0

Initialize it with the readonly modifier.

class Field {
    readonly _value: number;

    constructor(arg) {
        this._value = arg;
    }
}

Makes for a much cleaner implementation.

Elijah Mock
  • 587
  • 8
  • 21
-1

If you don't create a variable, it will not be accessible:

class Field{
    get value(){
        return 10;
    }

    set value(){
        console.log("cannot set");
    }
}

var obj = new Field();
console.log(obj.value); // 10
obj.value = 20;  // cannot set
console.log(obj.value); // 10 

Ofcourse I would recommend removing the set all-together:

class Field{
    get value(){
        return 10;
    }
}
basarat
  • 261,912
  • 58
  • 460
  • 511
  • Hi Basarat, appreciate your prompt responses. I think I didn't make my question clear. Edited it just now. Please have a look again. – FacePalm Mar 20 '13 at 06:00