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 protected constructor in TypeScript is a class constructor marked with the protected access modifier. It strictly confines direct instantiation (via the new operator) to the declaring class itself, while explicitly permitting derived classes to invoke it during their own initialization via super(). Derived classes cannot directly instantiate the base class using new; they are limited exclusively to the super() invocation.
class Base {
    protected constructor(public readonly id: string) {
        // Initialization logic
    }

    static createInternal(): Base {
        // Allowed: Direct instantiation within the declaring class's lexical scope
        return new Base("internal_id"); 
    }
}

class ExplicitlyDerived extends Base {
    // Explicitly overrides the access modifier to public
    public constructor() {
        // Allowed: Invoking the protected base constructor from a subclass via super()
        super("derived_id"); 
    }

    static attemptDirectBaseInstantiation() {
        // Compiler Error ts(2674): Constructor of class 'Base' is protected and 
        // only accessible within the class declaration.
        // return new Base("invalid"); 
    }
}

class ImplicitlyDerived extends Base {
    // No explicit constructor. The implicitly generated constructor 
    // inherits the `protected` access modifier from Base.
}

// @ts-expect-error: Compiler Error ts(2674): Constructor of class 'Base' is protected...
const baseInstance = new Base("external_id"); 

// Allowed: The derived class explicitly exposes a public constructor
const derivedInstance = new ExplicitlyDerived(); 

// @ts-expect-error: Compiler Error ts(2674): Constructor of class 'ImplicitlyDerived' is protected...
const implicitInstance = new ImplicitlyDerived("implicit_id");

Mechanical Behavior

  • Direct Instantiation Restriction: When the new operator is applied directly to a class with a protected constructor from any scope outside the declaring class itself—including within derived classes—the TypeScript compiler emits error ts(2674). Direct instantiation is exclusively confined to the declaring class.
  • Subclass Resolution: Derived classes can successfully resolve the super() call during their own instantiation phase. If a derived class does not explicitly declare a constructor, TypeScript’s implicitly generated constructor will automatically and legally invoke the protected base constructor. However, this implicitly generated constructor inherits the protected access modifier. Therefore, the derived class will also be uninstantiable from the outside unless it explicitly overrides the modifier by declaring a public constructor.
  • Internal Instantiation: The base class retains the ability to instantiate itself directly (e.g., new Base()) from within its own static methods or static properties.
  • Contrast with Private Constructors: A private constructor strictly confines both direct instantiation and invocation to the declaring class, completely prohibiting inheritance. TypeScript enforces this restriction at the declaration level by throwing an error directly on the extends clause (Error ts(2675): Cannot extend a class '...'. Class constructor is marked as private.), preventing the subclass from even being declared. A protected constructor permits inheritance and subclassing while maintaining the restriction on direct construction.
  • Runtime Erasure: Like all TypeScript access modifiers, the protected keyword is erased during compilation. At runtime, the emitted JavaScript constructor functions identically to a standard public constructor, meaning this restriction is enforced purely at compile-time by the TypeScript type checker.
Master TypeScript with Deep Grasping Methodology!Learn More