Private setter typescript?

TypescriptSetterGetter SetterAccessor

Typescript Problem Overview


Is there a way to have a private setter for a property in 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;
	}
}

Compiler complains that visibility for getter and setter don't match. I know I can just set the backing field, but but then I can't set breakpoints when the value is set.

I though about using an interface to hide the setter, but interfaces can only define a property, not whether it has a getter on setter.

Am I missing something here? There doesn't seem to be any reason to not allow private setters, the resulting JS doesn't enforce visibility anyway, and seems better that the current alternatives.

Am I missing something? If not is there a good reason for no private setters?

Typescript Solutions


Solution 1 - Typescript

The TypeScript specification (8.4.3) says...

> Accessors for the same member name must specify the same accessibility

So you have to choose a suitable alternative. Here are two options for you:

You can just not have a setter, which means only the Test class is able to set the property. You can place a breakpoint on the line 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!';

Probably the ideal way to ensure private access results in something akin to a "notify property changed" pattern can be implemented is to have a pair of private get/set property accessors, and a separate public get property accessor.

You still need to be cautious about someone later adding a direct call to the backing field. You could get creative in that area to try and make it less likely.

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

Solution 2 - Typescript

I also hope we could have public getter and private setter. Until we do, another way to handle this is to add additional private getter and setter:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsheamusView Question on Stackoverflow
Solution 1 - TypescriptFentonView Answer on Stackoverflow
Solution 2 - TypescriptsplintorView Answer on Stackoverflow