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.

In TypeScript, an override setter is a set accessor in a derived class annotated with the override keyword, explicitly declaring the intent to replace the assignment behavior of a property or setter inherited from a base class. When the noImplicitOverride compiler option is enabled in tsconfig.json, the compiler enforces a strict structural check, emitting an error if the base class does not possess a corresponding member to override.
class Base {
    protected _count: number = 0;

    set count(value: number) {
        this._count = value;
    }
}

class Derived extends Base {
    override set count(value: number) {
        this._count = Math.max(0, value);
    }
}

Technical Mechanics

1. Target Resolution and Runtime Caveats An override setter can legally target and replace two types of base class members: an existing set accessor, or a standard class property. Overriding a standard class property introduces a critical runtime caveat. If the useDefineForClassFields compiler option is enabled (which is the default for modern targets like ES2022 and later), the base class initializes the property directly on the instance. This instance property will shadow the derived class’s prototype accessors at runtime, meaning the setter will never be invoked when assigning to the property during or after base class instantiation.
class BaseProperty {
    data: string = ""; // Initialized on the instance
}

class DerivedAccessor extends BaseProperty {
    private _data: string = "";
    
    override get data(): string {
        return this._data;
    }

    // Valid in TS, but fails at runtime if useDefineForClassFields is true.
    // The base instance property 'data' shadows this prototype setter.
    override set data(value: string) {
        this._data = value;
    }
}
2. Type Compatibility and Contravariance To satisfy the Liskov Substitution Principle (LSP), the parameter type of the overriding setter must be contravariant. It must accept the exact type defined in the base class, or a wider (less specific) type. It cannot narrow the accepted type. When widening a setter’s parameter type, the property’s read capability dictates TypeScript’s structural checks:
  • Readable Properties: If the base class defines a readable property (either as a standard property or via a get accessor), the derived class can widen the setter’s parameter type as long as it explicitly provides a get accessor. This derived getter must return a type that is covariant (assignable) to the base class’s read type.
  • Write-Only Properties: If both the base and derived classes define only set accessors (omitting getters), the property is write-only. Write-only properties are strictly contravariant, meaning the derived setter can be widened without any covariant read-type checks.
  • Missing Read Contract: If the base class defines a readable property but the derived class overrides only the setter, the derived property becomes write-only. This results in a compiler error because the derived class fails to fulfill the read contract required by the base class.
class BaseType {
    // Base defines a standard readable property
    config: string | number = 0;
}

class DerivedType extends BaseType {
    private _config: string | number | boolean = 0;

    // Getter must be provided to satisfy the base class's covariant read contract
    override get config(): string | number { 
        return typeof this._config === "boolean" ? 0 : this._config; 
    }
    
    // Valid: Parameter type is wider (contravariant)
    override set config(value: string | number | boolean) { 
        this._config = value;
    }

    // Invalid: Parameter type is narrower. Will throw a compiler error.
    // override set config(value: string) { /* ... */ }
}
3. Access Modifier Restrictions The overriding setter cannot enforce a stricter visibility modifier than the base class member. If the base setter is public, the override setter must remain public. If the base setter is protected, the override setter can remain protected or be widened to public. 4. Getter/Setter Prototype Shadowing In JavaScript prototype chains, defining a setter on a derived prototype shadows the entire property descriptor of the base class. Consequently, overriding only the set accessor in the derived class does not automatically inherit the base get accessor. To maintain both read and write capabilities when extending behavior, the derived class must explicitly define both accessors, utilizing super calls if it needs to invoke the base class’s accessor logic.
Master TypeScript with Deep Grasping Methodology!Learn More