web-dev-qa-db-fra.com

Compositeur tapeur privé?

Existe-t-il un moyen d'avoir un setter privé pour une propriété dans TypeScript?

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

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

Le compilateur se plaint que la visibilité pour getter et setter ne correspond pas. Je sais que je peux simplement définir le champ de sauvegarde, mais je ne peux pas définir de points d'arrêt lorsque la valeur est définie.

J'ai pensé à utiliser une interface pour masquer le setter, mais les interfaces ne peuvent définir qu'une propriété, pas si elle a un getter sur le setter.

Est-ce que j'ai râté quelque chose? Il ne semble pas y avoir de raison de ne pas autoriser les setters privés, le JS résultant n'applique pas la visibilité de toute façon, et semble mieux que les alternatives actuelles.

Suis-je en train de manquer quelque chose? Sinon, y a-t-il une bonne raison pour qu'il n'y ait pas de colon privé?

60
sheamus

La spécification TypeScript (8.4.3) dit ...

Les accesseurs pour le même nom de membre doivent spécifier la même accessibilité

Vous devez donc choisir une alternative appropriée. Voici deux options pour vous:

Vous ne pouvez tout simplement pas avoir de setter, ce qui signifie que seule la classe Test est capable de définir la propriété. Vous pouvez placer un point d'arrêt sur la ligne 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!';

Le moyen idéal pour garantir que l'accès privé aboutit à quelque chose de semblable à un modèle "notifier la propriété modifiée" peut être implémenté est d'avoir une paire d'accesseurs de propriété get/set privés et un accesseur de propriété get séparé.

Vous devez toujours être prudent lorsque quelqu'un ajoute ultérieurement un appel direct au champ de sauvegarde. Vous pourriez devenir créatif dans ce domaine pour essayer de le rendre moins probable.

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';
    }
}
53
Fenton

J'espère aussi que nous pourrons avoir un getter public et un setter privé. Jusqu'à ce que nous le fassions, une autre façon de gérer cela est d'ajouter des getter et setter privés supplémentaires:

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;
  }
}
4
splintor