TypeScript - Typage Canard : Guide du Débutant

Salut à toi, future superstars du codage ! Aujourd'hui, nous allons plonger dans le merveilleux monde de TypeScript et explorer un concept qui est aussi amusant qu'il sonne - le Typage Canard. Ne t'inquiète pas si tu es nouveau dans le monde de la programmation ; je vais te guider à travers ce périple étape par étape, tout comme j'ai fait pour des centaines d'étudiants au fil des ans. Alors, mettons-nous à glousser !

TypeScript - Duck-Typing

Qu'est-ce que le Typage Canard ?

Imagine que tu es à un étang et que tu vois un oiseau nager. Il a l'air comme un canard, il coinque comme un canard, et il nage comme un canard. Comment l'appellerais-tu ? Un canard, bien sûr ! Eh bien, c'est l'essence même du Typage Canard dans la programmation !

Le Typage Canard est un concept qui dit : "Si ça marche comme un canard et qu'il coince comme un canard, alors c'est sûrement un canard." En termes de programmation, cela signifie que le type ou la classe d'un objet est moins important que les méthodes qu'il définit ou les propriétés qu'il a.

Permettez-moi de partager une petite histoire de mes jours d'enseignement. J'avais une fois une étudiante qui avait du mal à comprendre les types en programmation. Je lui ai demandé de penser à son étui à crayons. Peu importe s'il était fait de plastique, de métal ou de tissu - tant qu'il pouvait contenir ses stylos et crayons, il faisait bien son travail d'étui à crayons. C'est exactement le Typage Canard en action !

Comment le Typage Canard fonctionne en TypeScript

En TypeScript, le Typage Canard nous permet d'utiliser un objet comme s'il était d'un certain type, tant qu'il a toutes les propriétés et méthodes nécessaires de ce type. C'est comme dire : "Si il a toutes les fonctionnalités dont j'ai besoin, je ne me soucie pas de ce qu'il s'appelle !"

Regardons un exemple simple :

interface Quackable {
quack(): void;
}

function makeItQuack(duck: Quackable) {
duck.quack();
}

let rubberDuck = {
quack: () => console.log("Cris ! Cris !")
};

let realDuck = {
quack: () => console.log("Coinc ! Coinc !"),
swim: () => console.log("Plouf ! Plouf !")
};

makeItQuack(rubberDuck); // Output: Cris ! Cris !
makeItQuack(realDuck);   // Output: Coinc ! Coinc !

Dans cet exemple, nous avons une interface Quackable qui nécessite une méthode quack. Notre fonction makeItQuack accepte n'importe quel objet qui correspond à cette interface. Les objets rubberDuck et realDuck ont tous deux une méthode quack, donc ils peuvent tous deux être utilisés avec makeItQuack, même si realDuck a une méthode supplémentaire swim.

Avantages du Typage Canard

Maintenant que nous comprenons ce qu'est le Typage Canard, explorons pourquoi c'est si génial ! Voici quelques avantages clés :

1. Flexibilité

Le Typage Canard permet d'écrire du code plus flexible. Vous n'avez pas besoin de créer une hiérarchie stricte de classes pour utiliser des objets de manière similaire. Tant qu'un objet a les méthodes ou propriétés nécessaires, il peut être utilisé de manière interchangeable.

2. Réutilisabilité du Code

Avec le Typage Canard, vous pouvez écrire des fonctions qui fonctionnent avec un large éventail d'objets, tant qu'ils ont les propriétés ou méthodes nécessaires. Cela favorise la réutilisabilité du code et peut rendre votre base de code plus efficace.

3. Facilité de Test

Le Typage Canard rend plus facile la création d'objets simulés pour les tests. Vous n'avez besoin que d'implémenter les méthodes utilisées dans le test, plutôt que de créer une implémentation complète d'une classe.

4. Conception Intuitive

Le Typage Canard mène souvent à des conceptions d'API plus intuitives. Vous vous concentrez sur ce que peut faire un objet, plutôt que sur ce qu'il est étiqueté.

Exemples de Typage Canard en TypeScript

Plongons dans quelques exemples de plus pour renforcer notre compréhension du Typage Canard en TypeScript.

Exemple 1 : Le Changer de Forme

interface Drawable {
draw(): void;
}

class Circle {
draw() {
console.log("Dessiner un cercle");
}
}

class Square {
draw() {
console.log("Dessiner un carré");
}
}

function drawShape(shape: Drawable) {
shape.draw();
}

drawShape(new Circle()); // Output: Dessiner un cercle
drawShape(new Square()); // Output: Dessiner un carré

Dans cet exemple, Circle et Square sont des classes différentes, mais toutes deux ont une méthode draw. La fonction drawShape ne se soucie pas de la classe spécifique de l'objet qu'elle reçoit ; elle ne se soucie que l'objet ait une méthode draw.

Exemple 2 : Les Faisans Bruyants

interface NoiseMaker {
makeNoise(): string;
}

let dog = {
makeNoise: () => "Wouf !"
};

let cat = {
makeNoise: () => "Miaou !",
purr: () => "Ronron..."
};

let car = {
makeNoise: () => "Vroom !",
drive: () => console.log("Conduire...")
};

function makeNoise(thing: NoiseMaker) {
console.log(thing.makeNoise());
}

makeNoise(dog); // Output: Wouf !
makeNoise(cat); // Output: Miaou !
makeNoise(car); // Output: Vroom !

Ici, nous avons différents objets - un chien, un chat, et même une voiture ! Ils ont tous une méthode makeNoise, donc ils peuvent tous être utilisés avec la fonction makeNoise, même s'ils sont très différents.

Exemple 3 : Le Volant-Nageur

interface Flyable {
fly(): void;
}

interface Swimmable {
swim(): void;
}

class Duck implements Flyable, Swimmable {
fly() {
console.log("Le canard vole");
}
swim() {
console.log("Le canard nage");
}
}

class Airplane implements Flyable {
fly() {
console.log("L'avion vole");
}
}

class Fish implements Swimmable {
swim() {
console.log("Le poisson nage");
}
}

function makeFly(flyer: Flyable) {
flyer.fly();
}

function makeSwim(swimmer: Swimmable) {
swimmer.swim();
}

let duck = new Duck();
let airplane = new Airplane();
let fish = new Fish();

makeFly(duck);     // Output: Le canard vole
makeFly(airplane); // Output: L'avion vole
makeSwim(duck);    // Output: Le canard nage
makeSwim(fish);    // Output: Le poisson nage

Dans cet exemple, nous avons différentes classes implémentant différentes interfaces. La classe Duck implémente à la fois Flyable et Swimmable, donc elle peut être utilisée avec les fonctions makeFly et makeSwim.

Conclusion

Et voilà, amis ! Nous avons vadrouillé à travers les bases du Typage Canard en TypeScript. Souvenez-vous, le point clé est ceci : en Typage Canard, nous nous soucions plus de ce que peut faire un objet (ses méthodes et propriétés) que de ce qu'il est (son type ou sa classe).

Le Typage Canard nous permet d'écrire un code plus flexible, réutilisable et intuitif. C'est un concept puissant qui peut rendre votre code TypeScript plus élégant et efficace.

Alors, continuez votre voyage en programmation et gardez un œil ouvert pour les occasions d'appliquer le Typage Canard. Et souvenez-vous, si ça looks comme un canard, nage comme un canard, et coince comme un canard, alors c'est probablement un canard... ou du moins, il peut être traité comme tel dans votre code !

Bon codage, et que votre code toujours coince... euh, fonctionne parfaitement !

Credits: Image by storyset