Duck Typing is a way of programming in which an object passed into a function or method supports all method signatures and attributes expected of that object at run time. The object's type itself is not important. Rather, the object should support all methods/attributes called on it.
It refers to the ability to determine the compatibility of an object based on its shape or structure rather than its explicit type. It allows you to define interfaces that describe the expected structure of an object without explicitly specifying its type.
To create a duck-type interface in TypeScript, you can define an interface with the required properties and their types. Any object that has the same structure as the interface will be considered compatible.Example 1: Duck type
index.ts:
interface Duck {
quack(): void;
swim(): void;
}
function makeDuckSpeak(duck: Duck) {
duck.quack();
}
const realDuck = {
quack() {
console.log('Quack!');
},
swim() {
console.log('Swimming...');
}
};makeDuckSpeak(realDuck); // Output: Quack!
Example 2: Duck type
index.ts:
class Dog {
sound = "Dog: barking";
}
class Lion {
sound = "Lion: roaring";
}
class Goat {
sound = "Goat: bleat";
swim() {
console.log("Cannot Swim!");
}
}
let lion: Lion = new Dog(); // substitutes
let dog: Dog = new Lion(); // substitutes
let lionTwo: Lion = new Goat();
//let goat: Goat = new Lion(); // IDE & compiler error
console.log("Lion Sound: " + lion.sound);
console.log("Dog sound: " + dog.sound);
console.log("Lion sound: " + lionTwo.sound);
Note: In the above example, we can see that it does not allow the substitution of a Lion for a Goat because the Goat class has an additional method (so Lion fails duck typing). Dog and Lion are substitutable in duck typing because there's nothing a lion can do that a dog cannot.