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 TypeScript class is a blueprint for creating objects that encapsulates state (properties) and behavior (methods). It extends standard ECMAScript 2015 (ES6) classes by introducing static typing, access modifiers, and strict initialization checks, enforcing structural contracts at compile time.

Basic Syntax and Field Declarations

In TypeScript, class properties (fields) must be declared with their respective types before they are used. If the strictPropertyInitialization compiler option is enabled, fields must be initialized either at declaration or within the constructor. To bypass this strict initialization check—typically when properties are initialized indirectly via setup methods or dependency injection—TypeScript provides the definite assignment assertion operator (!).
class Point {
    x: number;
    y: number;
    label!: string; // Definite assignment assertion bypasses initialization checks

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    getCoordinates(): string {
        return `${this.x}, ${this.y} - ${this.label}`;
    }
}

Access Modifiers

TypeScript provides three access modifiers to control the visibility of class members:
  • public (default): The member is accessible from anywhere.
  • private: The member is accessible only within the declaring class.
  • protected: The member is accessible within the declaring class and any derived classes (subclasses).
Note on Encapsulation: TypeScript access modifiers are erased during compilation and only provide compile-time type checking. They do not prevent access at runtime. For true runtime privacy, use ECMAScript private fields (prefixed with #).
class Visibility {
    public a: string = "Public";
    private b: string = "Compile-time Private";
    protected c: string = "Protected";
    #d: string = "Runtime ECMAScript Private"; // Enforced at runtime
}

The readonly Modifier

The readonly modifier prevents a property from being reassigned after it has been initialized. It can only be assigned during declaration or inside the constructor. Note that readonly prevents reassignment of the property itself, not mutation of its internal state. If a readonly property holds a reference type (like an object or an array), its internal contents can still be modified at any time.
class Configuration {
    readonly environment: string;
    readonly tags: string[] = [];

    constructor(env: string) {
        this.environment = env; // Valid assignment
    }

    updateEnv() {
        // this.environment = "prod"; // Error: Cannot assign to 'environment'
        this.tags.push("v1"); // Valid: Mutating internal state of a reference type
    }
}

Parameter Properties

TypeScript offers a syntactic shorthand called parameter properties. By prefixing a constructor parameter with an access modifier (public, private, protected) or readonly, TypeScript automatically declares and initializes the class field in a single location.
class User {
    // Automatically creates 'id' and 'name' fields
    constructor(public readonly id: number, private name: string) {}
}

Accessors (Getters and Setters)

TypeScript supports get and set blocks to intercept read and write operations on a property. This allows for logic execution during property access while maintaining a standard property-access syntax.
class Temperature {
    private _celsius: number = 0;

    get fahrenheit(): number {
        return this._celsius * 9 / 5 + 32;
    }

    set fahrenheit(value: number) {
        this._celsius = (value - 32) * 5 / 9;
    }
}

Static Members

Static properties and methods belong to the class constructor object itself, rather than to instances of the class. They are accessed using the class name.
class MathUtility {
    static readonly PI: number = 3.14159;

    static calculateCircumference(radius: number): number {
        return 2 * MathUtility.PI * radius;
    }
}

Inheritance and Interfaces

Classes can inherit from a single base class using the extends keyword. A subclass inherits all members from its base class, including private ones. While private members are not directly accessible from the subclass’s code, they still exist on the instantiated object in memory and are utilized by inherited base class methods. Classes can also enforce structural contracts by implementing one or more interfaces using the implements keyword. TypeScript provides the override keyword to explicitly mark a method as overriding a base class method. Using this keyword prevents accidental signature mismatches or compile-time errors if the base class implementation changes or is removed. The noImplicitOverride compiler option can be enabled to force developers to use this keyword whenever an override occurs.
interface Loggable {
    log(): void;
}

class BaseEntity {
    constructor(public id: string) {}

    formatId(): string {
        return `ID-${this.id}`;
    }
}

class DocumentEntity extends BaseEntity implements Loggable {
    constructor(id: string, public title: string) {
        super(id); // Must call super() before accessing 'this'
    }

    override formatId(): string {
        return `DOC-${super.formatId()}`;
    }

    log(): void {
        console.log(`Document: ${this.title}`);
    }
}

Abstract Classes

Abstract classes serve as base classes that cannot be instantiated directly. They can contain both implemented methods and abstract methods. Abstract methods lack an implementation in the base class and force derived classes to provide the specific implementation.
abstract class DataProcessor {
    // Must be implemented by derived classes
    abstract process(data: string): void;

    // Shared implementation
    load(data: string): void {
        this.process(data);
    }
}

class JSONProcessor extends DataProcessor {
    process(data: string): void {
        JSON.parse(data);
    }
}
Master TypeScript with Deep Grasping Methodology!Learn More