5

When using getters and setters in object literals, I cannot see an easy way to access the outer "this" scope in Typescript. Consider the following:

class Report {
    stuff: any[];

    options = {
        length: 10,
        get maxLength() { return REPORT.stuff.length }
    }
}

Where REPORT wants to be a reference to the instance of the Report object. I realize that I can solve this by setting options within the constructor and using a var REPORT = this or similar, but seems inelegant. Is there a way to do this more cleanly?

Yona Appletree
  • 8,801
  • 6
  • 35
  • 52

2 Answers2

7

I realize that I can solve this by setting options within the constructor and using a var REPORT = this or similar, but seems inelegant

Instead of setting up option in the constructor you can take advantage of the fact that options *is being defined in the constructor. Thus, store this into options:

class Report {
    stuff: any[] = [];

    options = {
        _report: this,
        length: 10,
        get maxLength() { return (this._report as Report).stuff.length }
    }
}

let foo = new Report(); 
foo.stuff = [1,2];
console.log(foo.options.maxLength); // 2
basarat
  • 261,912
  • 58
  • 460
  • 511
2

You can take advantage of the this binding of lambdas.

class Report {
    stuff: any[];

    options = {
        length: 10,
        maxLength: () => this.stuff.length
    }
}

compiles to

var Report = (function () {
    function Report() {
        var _this = this;
        this.options = {
            length: 10,
            maxLength: function () { return _this.stuff.length; }
        };
    }
    return Report;
})();

Edit: This makes a function instead of a getter like you originally had. I assumed that was a typo, until just now, when I just learned that's valid javascript.

recursive
  • 83,943
  • 34
  • 151
  • 241
  • Unfortunately, that does not result in the same object as in my example. I want maxLength to be a _value property_, where as in your example, it's a function. To access the value in my example, you write `report.options.maxLength` in yours, you would need `report.options.maxLength()` – Yona Appletree Oct 26 '15 at 23:04
  • @YonaAppletree: Today, I learned that javascript has value properties. I've not seen them before. I know that fat-arrow lambdas can't be given names, so I don't see an elegant way of making such a getter. – recursive Oct 26 '15 at 23:06
  • I also just learned about getters / setters in object literals. I knew you could do it on an already-defined object with Object.defineProperty, but I did not know it was valid within a literal. I'm guessing this is where TypeScript got the syntax for it's property methods (or whatever they're actually called). – Yona Appletree Oct 28 '15 at 07:34