Setter privado typescript?


¿Hay alguna forma de tener un setter privado para una propiedad en 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;
    }
}

El compilador se queja de que la visibilidad de getter y setter no coinciden. Sé que solo puedo establecer el campo de respaldo, pero luego no puedo establecer puntos de interrupción cuando se establece el valor.

Pensé en usar una interfaz para ocultar el setter, pero las interfaces solo pueden definir una propiedad, no si tiene un getter en el setter.

¿Me estoy perdiendo algo aquí? No parece haber ninguna razón para no permitir setters privados, el JS resultante no impone visibilidad de todos modos, y parece mejor que las alternativas actuales.

¿Me estoy perdiendo algo? Si no, ¿hay una buena razón para que no haya setters privados?

Author: sheamus, 2015-01-07

2 answers

La especificación TypeScript (8.4.3) dice...

Los accesores para el mismo nombre de miembro deben especificar la misma accesibilidad

Así que tienes que elegir una alternativa adecuada. Aquí hay dos opciones para usted:

Simplemente no puede tener un setter, lo que significa que solo la clase Test es capaz de establecer la propiedad. Puede colocar un punto de interrupción en la línea 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!';

Probablemente la forma ideal de garantizar el acceso privado resulta en algo similar a un " notificar propiedad cambiada " se puede implementar el patrón es tener un par de accesores de propiedad get/set privados, y un accesor de propiedad get público separado.

Aún debe tener cuidado con que alguien agregue más tarde una llamada directa al campo de respaldo. Usted podría ser creativo en esa área para tratar de hacerlo menos 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';
    }
}
 41
Author: user75525,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-16 06:59:49

También espero que podamos tener público getter y setter privado. Hasta que lo hagamos, otra forma de manejar esto es agregar getter y setter privados adicionales:

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;
  }
}
 1
Author: splintor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-27 20:59:36