Inheritance, a significant feature of TypeScript, is primarily used for extending classes and interfaces. This feature enables new classes to inherit properties and methods from existing classes. Hence, the new classes can reuse the code from the base class with the option to add their own or even modify the existing functionalities.
To understand better, let's consider a practical example:
class Animal {
eat(): void {
console.log('Eating...');
}
}
class Dog extends Animal {
bark(): void {
console.log('Barking...');
}
}
let myDog = new Dog();
myDog.eat(); // Outputs: 'Eating...'
myDog.bark(); // Outputs: 'Barking...'
In the above code, Dog
class extends the Animal
class. The Dog
class thereby inherits the eat()
method from the Animal
class and also has its additional method bark()
. The myDog
instance of the Dog
class can call both eat()
and bark()
methods.
Inheritance can also be applied to interfaces in TypeScript. Here's how:
interface Vehicle {
start(): void;
}
interface Car extends Vehicle {
drive(): void;
}
let myCar: Car = {
start: () => console.log('Starting...'),
drive: () => console.log('Driving...')
}
With Car
interface extending Vehicle
interface, the Car
interface inherits the start()
method. Thus, any object of type Car
needs to define both start()
and drive()
methods.
This utilization of inheritance allows for cleaner, more understandable code by reducing redundancy.
As a best practice, it's crucial to only use inheritance when there is a clear, "is-a" relationship between two classes or interfaces. Avoiding complex multi-level inheritance hierarchies also helps keep the code easy to maintain and understand.