Open In App

How to Extend abstract class with Generics in Typescript ?

Last Updated : 13 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In Typescript, an abstract class is the base class that is inherited by other classes without having to define its members. Generic is the feature with which you can create a variable that represents a type in classes, functions, and type aliases that don’t need to define the types that they use explicitly.

There are 3 approaches given below to extend an abstract class with generics:

Using a basic way to extend the abstract class with Generics

In this approach, we will see the basic way to extend the abstract class with generics with 3 steps:

  • Create a class with an abstract keyword and add a generic type parameter using angle brackets (<>).
  • Use the generic type parameters in methods or properties within the abstract class.
  • Extend the abstract class from other classes by providing types for the generic parameters.

Syntax:

abstract class Classname<Generic> {
Visibility Prop_Name: Generic = Initial_Value;
Method_Name(Parameter: Generic): Return_Type{ ... }
}
class NormalClass extends Abstract_Class<Generic_Type> { ... }

Example : The below example will create a simple abstract class SuperClass with a generic type parameter T. It has a method pushItem that accepts an item of type T and stores it in an array of type T[].

Javascript




abstract class SuperClass<T> {
    protected NumArray: T[] = [];
 
    pushNumber(num: T): void {
        this.NumArray.push(num);
    }
 
    abstract ShowNumbers(): void;
}
 
class SubClass extends SuperClass<number> {
    showNumbers(): void {
        console.log("Pushed Numbers are: ",
        this.NumArray.join(", "));
    }
}
 
const numberSeries = new SubClass();
numberSeries.pushNumber(1);
numberSeries.pushNumber(2);
numberSeries.showNumbers();


Output:

Pushed Numbers are: 1, 2

Extending with Generic Constraints

Extending with the use of Generic Constraints can be done in the following 4 steps:

  • Create an interface of generic type with constraints
  • Create an abstract class with a generic type parameter constrained by the above interface
  • Extend the abstract class with a class that implements the interface
  • Extend the abstract class with the normal class by which the normal class will have the power to pass a class as a type

Syntax:

interface Interface_Name{ ... }
abstract class AbstractClass<T extends Interface_Name> { ... }
class ClassNameOne implements Interface_Name{ ... }
class ClassNameTwo extends AbstractClass<ClassNameOne > { ... }

Example: The below example creates a class that extends an abstract class with passing another class as a generic and the generic also extends some interface.

Javascript




interface MethodGateway {
    printName(): string;
}
 
abstract class AbstractClass<T extends MethodGateway> {
    abstract printName(): T;
}
 
class ClassMethodExtender implements MethodGateway {
    printName(): string {
        return "GeeksforGeeks";
    }
}
 
class NormalClass extends AbstractClass<ClassMethodExtender> {
    printName(): ClassMethodExtender {
        return new ClassMethodExtender();
    }
}
 
const instance = new NormalClass();
console.log(instance.printName().printName());


Output:

GeeksforGeeks

With multiple type parameters in Generics

Passing multiple Type parameters is explained in 2 steps below:

  • Create an abstract class with multiple generic type parameters like T,U…
  • Extend the abstract class with specific types

Syntax:

abstract class AbstractClass<T, U, ...> { ... }
class NormalClass extends AbstractClass<DataType_1, DataType_2, ...> { ... }

Example: The below example uses string type to pass to generic types that allows the abstract class to assign type to two abstract properties key and value.

Javascript




abstract class KeyValue<Key, Value> {
    abstract key: Key;
    abstract value: Value;
 
    abstract display(): void;
}
 
class StringType extends KeyValue<string, string> {
    key: string = "name";
    value: string = "GeeksforGeeks";
 
    display(): void {
        console.log(`Key: ${this.key}, Value: ${this.value}`);
    }
}
 
const instance = new StringType();
instance.display();


Output:

Key: name, Value: GeeksforGeeks


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads