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:
Table of Content
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[].
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.
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.
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