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 field in TypeScript is an unimplemented property declaration within an abstract class that mandates derived concrete classes to provide its implementation. It establishes a strict structural contract for subclasses without defining the underlying value, memory allocation, or initialization logic in the base class.

Syntax

Abstract fields are declared using the abstract keyword followed by the property name and its type annotation. They cannot contain an initializer. When combined with access modifiers, the access modifier must precede the abstract keyword.
abstract class BaseClass {
    abstract propertyName: Type;
    protected abstract protectedProperty: Type;
}

Technical Rules and Constraints

  1. Context Restriction: The abstract modifier for fields can only be used inside classes that are also marked as abstract.
  2. No Initialization: An abstract field cannot be assigned a value in the base class. Attempting to do so (e.g., abstract count: number = 0;) results in a compiler error.
  3. Access Modifiers: Abstract fields can be marked as public or protected. They cannot be marked as private, because a private field cannot be accessed or implemented by a derived class. The access modifier must strictly precede the abstract keyword (e.g., protected abstract, not abstract protected).
  4. Readonly Modifier: The readonly modifier can be combined with abstract. However, a derived class is allowed to implement an abstract readonly field as a standard, mutable property (omitting the readonly keyword). The readonly constraint only enforces immutability when the instance is accessed via the base class’s type reference.
  5. Definite Assignment: The TypeScript compiler enforces that any concrete subclass provides a definite assignment for the abstract field, either inline, in the constructor, or via accessors.

Implementation Mechanics

When a concrete class extends an abstract class, it must implement the abstract field. TypeScript’s structural typing system allows this contract to be satisfied in two ways: as a standard class property or as a getter/setter accessor.

1. Implementation via Class Property

The derived class declares the property and initializes it.
abstract class AbstractNode {
    abstract readonly id: string;
    protected abstract status: number;
}

class ConcreteNode extends AbstractNode {
    // Satisfied via inline initialization.
    // Note: The derived class can omit 'readonly', making it mutable here,
    // though it remains readonly when accessed as an AbstractNode.
    id: string = "node-001";
    
    // Satisfied via constructor initialization.
    protected status: number;

    constructor() {
        super();
        this.status = 1;
    }
}

2. Implementation via Accessors (Getters/Setters)

Because TypeScript evaluates properties structurally, an abstract field can be implemented using a get (and optionally set) accessor in the derived class.
class AccessorNode extends AbstractNode {
    // Satisfied via getter
    get id(): string {
        return "node-002";
    }

    // Satisfied via getter/setter pair
    private _status: number = 1;
    
    protected get status(): number {
        return this._status;
    }
    
    protected set status(value: number) {
        this._status = value;
    }
}

Abstract Fields vs. Abstract Getters/Setters

TypeScript also allows explicitly defining abstract accessors. However, defining an abstract field is generally preferred over abstract accessors unless the base class needs to enforce a specific accessor signature. An abstract field provides maximum flexibility to the derived class, allowing the implementer to choose between a standard property in memory or a dynamically computed accessor.
Master TypeScript with Deep Grasping Methodology!Learn More