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 static field in TypeScript is a class-level property bound directly to the class constructor object rather than to individual instances of the class. Declared using the static keyword, these fields share a single memory allocation. While static fields are excluded from the instance prototype chain (Class.prototype), they are included in the constructor’s prototype chain (e.g., Object.getPrototypeOf(Derived) === Base), which facilitates static property inheritance across subclasses.

Syntax and Access

Static fields are declared within the class body and are accessed via the class constructor object, rather than an instance reference.
class Entity {
    static entityCount: number = 0;
}

// Correct: Accessed via the class constructor
Entity.entityCount = 5;

const instance = new Entity();
// Compilation Error: Property 'entityCount' does not exist on type 'Entity'.
// instance.entityCount; 

Access Modifiers and Mutability

Static fields fully support TypeScript’s access modifiers (public, private, protected) as well as the readonly modifier. These modifiers dictate visibility and mutability strictly at the class level.
class Configuration {
    public static defaultTheme: string = "dark";
    private static readonly MAX_CONNECTIONS: number = 10;
    protected static activeNodes: number = 0;
}
  • private static: Accessible only within the declaring class.
  • protected static: Accessible within the declaring class and its subclasses.
  • static readonly: Can only be assigned during declaration or within a static initialization block.

Execution Context and this

The behavior of the this keyword changes depending on the execution context relative to static fields:
  1. Inside Static Methods: this refers to the class constructor object. You can use this.fieldName to access static fields.
  2. Inside Instance Methods: this refers to the class instance. To access static fields, the most idiomatic approach is to use the explicit class name (ClassName.fieldName). Alternatively, static fields can be accessed dynamically via the instance’s constructor.
class StateManager {
    static stateId: string = "INIT";

    static updateState() {
        // 'this' refers to the StateManager constructor object
        this.stateId = "RUNNING"; 
    }

    printState() {
        // Idiomatic: Explicit class name
        console.log(StateManager.stateId);
        
        // Dynamic: Accessed via the instance's constructor
        console.log((this.constructor as typeof StateManager).stateId);
    }
}

Generics and Type Erasure

Static fields cannot reference class type parameters. Because TypeScript’s generic types are erased at runtime, only a single class constructor object exists in memory for all generic instantiations (e.g., Container<string> and Container<number> share the exact same Container constructor).
class Container<T> {
    // Compilation Error: Static members cannot reference class type parameters.
    // static defaultItem: T; 
    
    static version: number = 1; // Allowed
}

Reserved Property Names

Because class constructors are standard JavaScript functions under the hood, static fields cannot use reserved function property names. Declaring a static field with names such as name, length, or call will result in a compilation error.
class Process {
    // Compilation Error: Static property 'name' conflicts with built-in property
    // static name: string = "BackgroundProcess"; 
    
    // Compilation Error: Static property 'length' conflicts with built-in property
    // static length: number = 10;
}

Inheritance and Shadowing

Static fields are inherited by subclasses via the constructor prototype chain. A subclass can access the parent’s static fields directly. If a subclass declares a static field with the exact same name, it shadows the parent’s static field without mutating the parent’s value.
class Base {
    static version: number = 1;
}

class Derived extends Base {
    // Inherits Base.version implicitly
    
    // Shadows the parent static field
    static version: number = 2; 
}

console.log(Base.version);    // 1
console.log(Derived.version); // 2

Static Initialization Blocks

For complex initialization logic that cannot be handled by inline assignment, TypeScript supports static initialization blocks (static {}). These blocks execute exactly once when the class is evaluated by the JavaScript engine.
class Dictionary {
    static readonly words: string[];

    static {
        // Complex initialization logic
        const temp = ["alpha", "beta", "gamma"];
        this.words = temp.filter(w => w.length > 4);
    }
}
Master TypeScript with Deep Grasping Methodology!Learn More