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.

An abstract class in TypeScript is a restricted class declared with the abstract modifier that serves exclusively as a base class. It cannot be instantiated directly using the new keyword. Instead, it establishes a strict structural contract for derived classes by combining fully implemented members with abstract members (properties and methods) that lack implementation.

Syntax and Structure

Abstract classes are defined using the abstract keyword before the class declaration. Members within the class that require implementation by subclasses are also prefixed with abstract.
abstract class AbstractBase {
    // Abstract property: defines type, but no initialization
    abstract identifier: string;

    // Abstract method: defines signature, but no body
    abstract executeAction(payload: string): boolean;

    // Concrete method: fully implemented, inherited by subclasses
    logAction(message: string): void {
        console.log(`[LOG]: ${message}`);
    }
}

Core Mechanics and Rules

  1. Instantiation Restriction: The TypeScript compiler will throw an error if you attempt to instantiate an abstract class directly (new AbstractBase()).
  2. Implementation Mandate: Any concrete (non-abstract) class that extends an abstract class must implement all inherited abstract properties and methods. If a derived class fails to implement even one abstract member, it must also be declared as abstract.
  3. Method Signatures and Type Variance: Abstract methods only define the call signature (parameters and return type). They are terminated with a semicolon instead of a block {}. When implementing these methods, class methods defined using the methodName(arg: Type): void syntax are bivariant in TypeScript. This means a derived class can implement an abstract method with a narrower or wider parameter type without triggering a compiler error.
  4. Access Modifiers:
    • Abstract members can be public or protected.
    • Abstract members cannot be private, as derived classes would be unable to access and implement them.
    • Abstract members cannot be static.
  5. Constructors: Abstract classes can define constructors. A derived class is only required to explicitly call super() if it defines its own constructor block. If the derived class omits the constructor entirely, TypeScript automatically calls the base class constructor upon instantiation, inheriting the base constructor’s parameter signature.

Implementation Example

To safely handle varying data types in derived classes, abstract classes frequently utilize generic type parameters.
abstract class DataProcessor<T> {
    constructor(protected processorName: string) {}

    // Must be implemented by derived classes
    abstract dataFormat: string;
    abstract process(data: T): void;

    // Inherited as-is
    getProcessorInfo(): string {
        return `Processor: ${this.processorName}, Format: ${this.dataFormat}`;
    }
}

class JSONProcessor extends DataProcessor<string> {
    // Fulfilling the abstract property contract
    dataFormat = "JSON";

    // Explicit constructor requires a call to super()
    constructor() {
        super("JSON_V1"); 
    }

    // Fulfilling the abstract method contract
    process(data: string): void {
        const parsed = JSON.parse(data);
        console.log(parsed);
    }
}

class XMLProcessor extends DataProcessor<string> {
    dataFormat = "XML";

    // Constructor omitted; TypeScript automatically calls the base constructor.
    // Instantiation requires passing the base constructor arguments.

    process(data: string): void {
        console.log(`<xml>${data}</xml>`);
    }
}

// const base = new DataProcessor<string>("Base"); // TS Error: Cannot create an instance of an abstract class.

const jsonProc = new JSONProcessor(); // Valid: constructor takes 0 arguments
jsonProc.process('{"key": "value"}');

const xmlProc = new XMLProcessor("XML_V1"); // Valid: inherits base constructor signature
xmlProc.process('data');

Compilation Behavior

Unlike TypeScript interface declarations, which are completely erased during compilation, abstract classes are emitted into the final JavaScript code as standard ES6 classes. The abstract keywords are stripped away, but the concrete methods, properties, and constructors remain intact in the compiled output, allowing them to be utilized at runtime via prototype chain inheritance.
Master TypeScript with Deep Grasping Methodology!Learn More