Private Setter Typoskript?


73

Gibt es eine Möglichkeit, einen privaten Setter für eine Eigenschaft in TypeScript zu haben?

class Test
{
    private _prop: string;
    public get prop() : string
    {
        return this._prop;
    }

    private set prop(val: string)
    {
        //can put breakpoints here
        this._prop = val;
    }
}

Der Compiler beschwert sich darüber, dass die Sichtbarkeit für Getter und Setter nicht übereinstimmt. Ich weiß, dass ich nur das Hintergrundfeld festlegen kann, aber dann kann ich keine Haltepunkte festlegen, wenn der Wert festgelegt ist.

Ich habe überlegt, eine Schnittstelle zu verwenden, um den Setter auszublenden, aber Schnittstellen können nur eine Eigenschaft definieren, nicht, ob sie einen Getter auf Setter hat.

Vermisse ich hier etwas? Es scheint keinen Grund zu geben, private Setter nicht zuzulassen, die resultierende JS erzwingt ohnehin keine Sichtbarkeit und scheint besser zu sein als die aktuellen Alternativen.

Vermisse ich etwas Wenn nicht, gibt es einen guten Grund für keine privaten Setter?

Antworten:


68

Die TypeScript-Spezifikation (8.4.3) sagt ...

Accessoren für denselben Mitgliedsnamen müssen dieselbe Barrierefreiheit angeben

Sie müssen also eine geeignete Alternative wählen. Hier sind zwei Optionen für Sie:

Sie können einfach keinen Setter haben, was bedeutet, dass nur die TestKlasse die Eigenschaft festlegen kann. Sie können einen Haltepunkt auf der Linie platzieren this._prop =....

class Test
{
    private _prop: string;
    public get prop() : string
    {
        return this._prop;
    }

    doSomething() {
        this._prop = 'I can set it!';
    }
}

var test = new Test();

test._prop = 'I cannot!';

Der wahrscheinlich ideale Weg, um sicherzustellen, dass ein privater Zugriff zu einem ähnlichen Muster wie "Benachrichtigen von Eigenschaften geändert" führt, besteht darin, ein Paar privater Zugriffsberechtigungen zum Abrufen / Festlegen von Eigenschaften und einen separaten öffentlichen Zugriffsberechtigten zum Abrufen von Eigenschaften zu haben.

Sie müssen immer noch vorsichtig sein, wenn jemand später einen direkten Anruf zum Hintergrundfeld hinzufügt. Sie könnten in diesem Bereich kreativ werden, um zu versuchen, die Wahrscheinlichkeit zu verringern.

class Test
{
    private _nameBackingField: string;

    private get _name() : string
    {
        return this._nameBackingField;
    }

    private set _name(val: string)
    {
        this._nameBackingField = val;
        // other actions... notify the property has changed etc
    }

    public get name(): string {
        return this._name;
    }

    doSomething() {
        this._name += 'Additional Stuff';
    }
}

2
Das Problem mit dieser Lösung ist, dass sie nicht erlauben + = (und - =) Operator:this.prop += 'abc';
Schiene

3
@splintor ja, aber nicht zulassen, dass andere den Wert ändern, ist der
Tobias J

@TobyJ Beachten Sie die, die thisich in meinem Beispiel verwendet habe. Ich meine zulassen +=und -=innerhalb der Klasse, wo Sie einen Haltepunkt setzen können. Die @ Fenton-Lösung schlägt vor, eine Methode hinzuzufügen, die Sie jedoch innerhalb der Klasse nicht +=hinzufügen können prop. In meiner Lösung finden Sie eine Möglichkeit, dies zu tun.
Schiene

@splintor im ersten Beispiel, das Sie verwenden könnenthis._prop += 'I can set it!';
Fenton

@Fenton Natürlich kann ich das, aber wenn ich möchte, dass der Setter mehr als nur das _propFeld einstellt , z. B. call notify('_prpo', value), dann reicht das _propdirekte Einstellen nicht aus.
Schiene

6

Ich hoffe auch, dass wir einen öffentlichen und einen privaten Setter haben könnten. Bis wir dies tun, besteht eine andere Möglichkeit, dies zu handhaben, darin, zusätzliche private Getter und Setter hinzuzufügen:

class Test {
  _prop: string;
  public get prop(): string {
    return this._prop;
  }

  private get internalProp(): string {
    return this.prop;
  }

  private set internalProp(value: string) {
    this._prop = value;
  }

  private addToProp(valueToAdd: string): void {
    this.internalProp += valueToAdd;
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.