Duck Typing

Duck Typing

The circumstance where an object’s type is decided by its behavior, like methods and attributes, rather than its class is known as “duck typing”.

The usage of interfaces in TypeScript makes duck typing possible. Where interface means the set of methods and characteristics an object must have to fall under that type are described.

For example, if an interface defines the function, any object with the method called “myFunc()” may be treated as belonging to a specific kind, regardless of its class.

Duck typing emphasizes assessing an object’s suitability for a task by considering its methods and attributes instead of its actual type. An interface explains the set of properties and methods an object must have to be considered “duck typed” for a particular purpose.

Benefits of Duck Typing

One of duck typing’s main benefits is making code more flexible and reusable. The code works with any object with the required methods and properties rather than just particular types of objects and may be used in various situations without requiring modification. Duck typing also improves code reuse by enabling the interchangeable usage of objects of diverse kinds within a single codebase.

Exmaples of Duck Typing is TypeScript

Here is an example of how to use duck typing in TypeScript

Define an interface that represents the behaviour you want an object to have. For example

interfaceDuck{quack():void;}

Create a class that implements the interface. For example

classMallardDuckimplementsDuck{quack():void{
  console.log("Quack!");}}</code></pre>

Create an instance of the class and use it as the type defined by the interface.

let duck: Duck =newMallardDuck();
duck.quack();// Output: "Quack!"

Create another class that also implements the interface

classRubberDuckimplementsDuck{quack():void{
  console.log("Squeak!");}}</code></pre>

Use the new class instance as the same type defined by the interface.

let duck: Duck =newRubberDuck();
duck.quack();// Output: "Squeak!"

As you can see, both MallardDuck and RubberDuck classes implement the Duck interface, and the duck variable can be assigned to instances of both classes. The type is determined by the behaviour (methods and properties) defined in the interface rather than the class.

It's also important to note that in typescript, you can use the typeof keyword to check the type of object in runtime and if the object has the expected method or property.

Example

In this example, the Bird and Plane classes implement the Flyable interface, which requires a fly() method. Both "duck types" can be used interchangeably in the goFly() function. The function doesn't care about the actual type of the object passed to it as long as it has a fly() method that can be called.

interfaceFlyable{fly():void;}classBirdimplementsFlyable{fly():void{
  console.log("Bird is flying");}}classPlaneimplementsFlyable{fly():void{
  console.log("Plane is flying");}}functiongoFly(flyable: Flyable){
flyable.fly();}let bird =newBird();let plane =newPlane();goFly(bird);// Prints "Bird is flying"goFly(plane);// Prints "Plane is flying"

On compiling, it will generate the following JavaScript code

var Bird =/** @class */(function(){functionBird(){}
   Bird.prototype.fly=function(){console.log("Bird is flying");};return Bird;}());var Plane =/** @class */(function(){functionPlane(){}
   Plane.prototype.fly=function(){console.log("Plane is flying");};return Plane;}());functiongoFly(flyable){
   flyable.fly();}var bird =newBird();var plane =newPlane();goFly(bird);// Prints "Bird is flying"goFly(plane);// Prints "Plane is flying"

Output

The above code will produce the following output

Bird is flying
Plane is flying

Example

Overall, duck typing is a powerful programming concept that allows for greater flexibility and reusability in TypeScript code by allowing objects of different types to be used interchangeably as long as they have the same methods and properties. In this example, the Driveable interface, Car and Truck classes show the same thing.

interfaceDriveable{drive():void;}classCarimplementsDriveable{drive():void{
console.log("Car is driving");}}classTruckimplementsDriveable{drive():void{
console.log("Truck is driving");}}functiongoDrive(driveable: Driveable){
driveable.drive();}let car =newCar();let truck =newTruck();goDrive(car);// Prints "Car is driving"goDrive(truck);// Prints "Truck is driving"

On compiling, it will generate the following JavaScript code

var Car =/** @class */(function(){functionCar(){}
Car.prototype.drive=function(){console.log("Car is driving");};return Car;}());var Truck =/** @class */(function(){functionTruck(){}
Truck.prototype.drive=function(){console.log("Truck is driving");};return Truck;}());functiongoDrive(driveable){
driveable.drive();}var car =newCar();var truck =newTruck();goDrive(car);// Prints "Car is driving"goDrive(truck);// Prints "Truck is driving"</code></pre>

Output

The above code will produce the following output

Car is driving
Truck is driving

The main idea behind duck typing is that the code should be written to work with any object with the methods and properties it needs, rather than being written to work with specific objects. This can make the code more flexible and reusable, allowing you to use different types of objects interchangeably without changing the code.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *