Fionn
Fionn

Reputation: 11295

Access the getter and setter of a typescript property

I have a question about typescript properties: Is it possible to get the setter and getter of a typescript property or to declare a function argument to be of a property of X type?

The reason is to get some sort of "reference" to a variable which is not possible in plain JS without writing getter/setter wrappers or access the variable via parent object itself (obj["varname"]).

For example (with some working code and other parts speculative):

//A sample class with a property
class DataClass<T> {
    private T val;

    public get value(): T {
        return this.val;
    }

    public set value(value: T) {
        this.val = value;
    }
}

//Different ways of modifing a member "by reference"
class ModifyRef {
    public static void DoSomethingByGetterAndSetter(getter: () => string, setter: (val: string) => void) {
        var oldValue = getter();
        setter("new value by DoSomethingByGetterAndSetter");
    }

    public static void DoSomethingByObject(obj: Object, name: string) {
        var oldValue = obj[name];
        obj[name] = "new value by DoSomethingByObject";
    }

    //Is something like this possible?
    public static void DoSomethingByProperty(somePropery: property<string>) {
        var oldVlaue = someProperty;
        someProperty = "new value by DoSomethingByProperty";
    }
}

var inst = new DataClass<string>();

//Calling the DoSomethingByProperty if possible
ModifyRef.DoSomethingByProperty(inst.value);

//Or if not is something like this possible
ModifyRef.DoSomethingByGetterAndSetter(inst.value.get, inst.value.set);

Upvotes: 0

Views: 3243

Answers (2)

Daniel Earwicker
Daniel Earwicker

Reputation: 116744

I've long found it very surprising that languages with properties don't include a convenient way to make a reference to a property, and have daydreamed about having this feature in C#. It ought to work on local variables as well.

A popular pattern for this kind of first-class or reified property is a single function that can be called in two ways:

  1. no arguments: returns current value.
  2. one argument: sets value, returns undefined.

Or in TypeScript terms:

interface Property<T> {
    (): T;
    (newVal: T): void;
}

The methods of jQuery objects often work like this. An example of this pattern in modelling pure data is in Knockout, in which such properties also support change subscriptions, and there's a rather elegant pattern for defining computed properties that automatically recompute when their dependencies change.

Upvotes: 0

Fenton
Fenton

Reputation: 251242

The simplest way to do this would be to provide methods, rather than a property:

//A sample class with a property
class DataClass<T> {
    private val: T;

    public getValue(): T {
        return this.val;
    }

    public setValue(value: T) {
        this.val = value;
    }
}

class ModifyRef {
    public static DoSomethingByGetterAndSetter(getter: () => string, setter: (val: string) => void) {
        var oldValue = getter();
        setter("new value by DoSomethingByGetterAndSetter");
    }
}

var inst = new DataClass<string>();

//Or if not is something like this possible
ModifyRef.DoSomethingByGetterAndSetter(inst.getValue, inst.setValue);

Upvotes: 1

Related Questions