liveBook · Manning

Subclass

As explained in Essential TypeScript 5, Third Edition

A subclass is a class derived from another class that can inherit or extend its members and behavior.

A subclass derives from another class with `extends`. Use one when a new class needs the existing class’s behavior but must add or specialize features. If the subclass declares a constructor, it must call the superclass constructor with `super(...)` so inherited properties are initialized. section 11.3.7

Extend a class

In `src/index.ts`, `class Employee extends Person` calls `super(id, name, city)` in its constructor, then adds a department and a `writeDept()` method. The shared `Person` properties remain available alongside the employee-specific behavior. section 11.3.7

Do not assume an array’s inferred type records the superclass you have in mind. An array containing an `Employee` and a `Customer` can be inferred as `(Employee | Customer)[]`; adding a different `Person` subclass may then fail. Declare `let data: Person[]` when the array should accept any of those subclasses. TypeScript checks object shapes when resolving the inferred type. section 11.3.7

Listing 11.19 Using a type annotation in the index.ts file in the src folder
...
let data: Person[] = [new Employee("fvega", "Fidel Vega", "Sales", 
    "Paris"), new Customer("ajones", "Alice Jones", "London", 500)];
data.push(new Supplier("dpeters", "Dora Peters", "New York", "Acme"));
...

See the explicit `Person[]` annotation that lets the array accept several subclasses. section 11.3.7

Add persistent storage without replacing the collection API

In `src/todoCollection.ts`, changing `itemMap` to `protected` lets subclasses access it while keeping it unavailable to unrelated code. In `src/jsonTodoCollection.ts`, `JsonTodoCollection extends TodoCollection` calls `super(userName, [])`, then uses Lowdb to read tasks from `Todos.json` or initialize the file from supplied items. The application can hold the result as `let collection: TodoCollection = new JsonTodoCollection("Adam", todos);`. section 2.5

Subclasses can also complete an abstract class: `ArrayCollection<T>` supplies `add` and `count`, while its `ProductCollection` and `PersonCollection` subclasses implement the abstract `get` method for their respective types. A class decorator can instead return a subclass to add a method, but that method does not automatically appear in the decorated class’s TypeScript type; an interface and type guard provide type-safe access. section 12.4.2 section 14.3.1

Listing 12.26 Defining an abstract class in the index.ts file in the src folder
import { City, Person, Product, Employee } from "./dataTypes.js";

type  shapeType = { name: string };

interface Collection<T extends shapeType> {

    add(...newItems: T[]): void;
    get(name: string): T;
    count: number;
}

abstract class ArrayCollection<T extends shapeType> 
        implements Collection<T> {
    protected items: T[] = [];
        
    add(...newItems: T[]): void {
        this.items.push(...newItems);
    }

    
    abstract get(searchTerm: string): T;
        
    get count(): number {
        return this.items.length;
    }
}

class ProductCollection extends ArrayCollection<Product> {

    get(searchTerm: string): Product {
        return this.items.find(item => item.name === searchTerm);
    }
}

class PersonCollection extends ArrayCollection<Person> {

    get(searchTerm: string): Person {
        return this.items.find(item => 
            item.name === searchTerm || item.city === searchTerm);        
    }
}

let peopleCollection: Collection<Person> = new PersonCollection();
peopleCollection.add(new Person("Bob Smith", "London"), 
    new Person("Dora Peters", "New York"));
let productCollection: Collection<Product> = new ProductCollection();
productCollection.add(new Product("Running Shoes", 100), 
    new Product("Hat", 25));
[peopleCollection, productCollection].forEach(c => 
    console.log(`Size: ${c.count}`));

Compare the abstract collection’s shared implementation with the `get` methods supplied by its subclasses. section 12.4.2

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through constructors, protected access, array type inference, and abstract methods; flags the type limitation of decorator-created subclasses.
Examples
Uses employee and customer arrays, a JSON-backed to-do collection, an abstract collection, and a decorator that adds serialization.
What it assumes
Builds on class constructors and arrays while introducing TypeScript’s protected access and inferred array types through examples.
What you can do after
Build it from scratch by extending a class, initializing its superclass, and annotating mixed-subclass arrays when needed.
How it connects
Connects subclasses to `extends`, `super`, protected properties, type inference, abstract classes, generic interfaces, and class decorators.

Also explained in

Compare how 2 books explain subclass →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.