Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A private setter in TypeScript is a class member configuration where the set accessor is assigned a more restrictive access modifier (private or protected) than its corresponding get accessor. Introduced in TypeScript 4.3, this feature allows a property to be publicly readable during static analysis while restricting mutation strictly to the internal lexical scope of the class.

Syntax

To implement a private setter, apply the private (or protected) keyword directly to the set method declaration, while leaving the get method with a broader visibility modifier (typically public).
class StateContainer {
    private _internalCount: number = 0;

    // Publicly accessible accessor
    public get count(): number {
        return this._internalCount;
    }

    // Internally restricted mutator
    private set count(value: number) {
        this._internalCount = value;
    }

    public increment(): void {
        // Valid: Internal class methods can invoke the private setter
        this.count++; 
    }
}

const container = new StateContainer();
console.log(container.count); // Valid: Returns 0
container.count = 5;          // Error: Property 'count' cannot be assigned to because it is a read-only property outside the class.

Technical Constraints and Rules

  1. Visibility Hierarchy: The access modifier on the setter must be strictly more restrictive than the modifier on the getter. A public getter can pair with a protected or private setter. A protected getter can pair with a private setter. You cannot define a private getter with a public setter.
  2. Implicit Getter Visibility: If no access modifier is explicitly defined on the getter, it defaults to public. The setter must then explicitly declare its narrower scope.
  3. Type Compatibility: While TypeScript 4.3+ allows getters and setters to have different types, the type returned by the getter must be assignable to the type accepted by the setter.
  4. Compile-Time Enforcement: The private keyword is a TypeScript-specific construct. The access restriction is enforced entirely by the TypeScript compiler during static analysis.
  5. Runtime Erasure: Upon compilation to JavaScript, the private modifier is erased. The resulting JavaScript will output standard get and set functions on the class prototype. Because JavaScript property descriptors cannot have mixed runtime visibility, the setter remains publicly accessible at runtime.

ECMAScript Runtime Equivalent

To achieve strict runtime encapsulation that mirrors the behavior of a TypeScript private setter, you cannot use the private set syntax, as it exposes the setter in the emitted JavaScript. Instead, you must omit the set accessor entirely—making the property strictly read-only from the outside—and mutate an ECMAScript private field (#) directly from within internal class methods.
class RuntimeStateContainer {
    // ECMAScript private field (hard runtime privacy)
    #internalCount: number = 0;

    // Public getter exposes the value
    public get count(): number {
        return this.#internalCount;
    }

    // No setter is defined on the property descriptor.
    // Internal mutations target the private field directly.
    public increment(): void {
        this.#internalCount++;
    }
}

const runtimeContainer = new RuntimeStateContainer();
console.log(runtimeContainer.count); // 0
runtimeContainer.count = 5;          // TypeError at runtime: Cannot set property count of #<RuntimeStateContainer> which has only a getter
Master TypeScript with Deep Grasping Methodology!Learn More