TypeScript -Compatibilité des Types

Bonjour là-bas, futurs magiciens de la programmation ! Aujourd'hui, nous allons entreprendre un voyage passionnant dans le monde de TypeScript et explorer le fascinant concept de compatibilité des types. Ne vous inquiétez pas si vous êtes nouveau dans la programmation - je serai votre guide amical, et nous aborderons ce sujet étape par étape. Alors, sortez vos baguettes virtuelles (claviers), et mettons-nous à jeter quelques sorts TypeScript !

TypeScript - Type Compatibility

Comment TypeScript effectue les vérifications de compatibilité des types ?

Imaginez que vous essayez de faire rentrer des blocs de formes différentes dans un trou. La compatibilité des types de TypeScript est un peu comme ça - il s'agit de savoir si un type peut rentrer dans un autre. Mais au lieu de formes physiques, nous travaillons avec des types de données.

Typage structural

TypeScript utilise ce que nous appelons le "typage structural". Cela signifie qu'il se soucie davantage de la forme d'un objet que de son nom exact de type. Jetons un coup d'œil à un exemple :

interface Pet {
name: string;
}

class Dog {
name: string;
}

let pet: Pet;
let dog = new Dog();

pet = dog; // Ça va bien !

Dans cette ménagerie magique, TypeScript dit : "Hey, Pet et Dog ont tous deux une propriété name de type string. Ils ont l'air les mêmes pour moi, donc ils sont compatibles !" C'est comme dire qu'un bouchon carré rentre dans un trou carré, même si l'un est appelé "carré" et l'autre "bloc".

Typage canard

Il y a une expression amusante en programmation : "Si ça marche comme un canard et qu'il coasse comme un canard, alors c'est sûrement un canard." Voici l'essence du typage canard, et TypeScript adopte cette philosophie. Voyons-le en action :

interface Quacker {
quack(): void;
}

class Duck {
quack() {
console.log("Quack !");
}
}

class Person {
quack() {
console.log("J'imiterais un canard !");
}
}

let quacker: Quacker = new Duck(); // Bien sûr, c'est correct
quacker = new Person(); // Ça va aussi !

TypeScript ne se soucie pas que Person n'est pas explicitement déclaré comme un Quacker. Il ne se soucie que Person a une méthode quack, tout comme Quacker. Donc, Duck et Person sont tous deux compatibles avec Quacker.

Comment utiliser la compatibilité des types efficacement ?

Utiliser la compatibilité des types efficacement, c'est comme être un solveur de puzzles chevronné. Voici quelques conseils :

1. Comprendre les vérifications des littéraux d'objets

TypeScript est plus strict avec les littéraux d'objets. Voyons pourquoi :

interface Point {
x: number;
y: number;
}

let p: Point;

// Ça va bien
p = { x: 10, y: 20 };

// Cela provoquera une erreur
p = { x: 10, y: 20, z: 30 };

TypeScript dit : "Whoa là ! J'ai demandé un Point, mais vous me donnez quelque chose de supplémentaire (z). Ça n'est pas permis !" Cela aide à attraper des bugs potentiels où vous pourriez utiliser un objet incorrectement.

2. Utiliser des propriétés optionnelles

Parfois, vous voulez être plus flexible. C'est là que les propriétés optionnelles deviennent utiles :

interface Options {
color?: string;
width?: number;
}

function configure(options: Options) {
// ...
}

configure({ color: "red" }); // Bien
configure({ width: 100 }); // Bien
configure({}); // Ça va aussi !

En rendant les propriétés optionnelles (avec le ?), vous dites à TypeScript : "C'est correct si elles ne sont pas toujours là."

Fonctions et compatibilité des types

Les fonctions sont comme les couteaux suisses de la programmation - elles sont incroyablement polyvalentes. Voyons comment la compatibilité des types fonctionne avec elles :

Compatibilité des paramètres

TypeScript est étonnamment tolérant avec les paramètres de fonction :

let x = (a: number) => 0;
let y = (b: number, s: string) => 0;

y = x; // Ça va
x = y; // Erreur

Cela peut sembler contre-intuitif, mais c'est sûr. TypeScript dit : "Si vous attendez une fonction qui prend deux paramètres, il est acceptable de lui donner une fonction qui en prend moins. Le paramètre supplémentaire sera simplement ignoré."

Compatibilité des types de retour

Les types de retour doivent également être compatibles :

let x = () => ({name: "Alice"});
let y = () => ({name: "Alice", location: "Wonderland"});

x = y; // Ça va
y = x; // Erreur

Il est acceptable de retourner plus que prévu, mais pas moins. C'est comme commander une pizza et obtenir des toppings supplémentaires gratuitement - c'est génial ! Mais si vous avez commandé une pizza avec des toppings et que vous n'obtenez que la croûte, vous seriez déçu.

Classes et compatibilité des types

Les classes sont comme des plans pour des objets, et elles suivent des règles de compatibilité similaires :

class Animal {
feet: number;
constructor(name: string, numFeet: number) { }
}

class Size {
feet: number;
}

let a: Animal;
let s: Size;

a = s; // Ça va
s = a; // Ça va

TypeScript ne se soucie que des membres d'instance. Il dit : "Les deux ont une propriété feet ? C'est suffisant pour moi !"

Membres privés et protégés

Cependant, lorsque les classes ont des membres privés ou protégés, les choses deviennent plus strictes :

class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}

class Rhino extends Animal {
constructor() { super("Rhino"); }
}

class Employee {
private name: string;
constructor(theName: string) { this.name = theName; }
}

let animal = new Animal("Goat");
let rhino = new Rhino();
let employee = new Employee("Bob");

animal = rhino; // Ça va
animal = employee; // Erreur : 'Animal' et 'Employee' ne sont pas compatibles

Même si Animal et Employee se ressemblent, TypeScript les traite comme différentes parce que leurs membres private proviennent de déclarations différentes.

Conclusion

Et voilà, mes apprentis codeurs ! Nous avons parcouru le pays de la compatibilité des types de TypeScript. Souvenez-vous, TypeScript est là pour vous aider à écrire un code meilleur et plus sûr. C'est comme avoir un magicien amical qui veille sur vous, vous poussant doucement lorsque vous êtes sur le point de faire une erreur.

Continuez à pratiquer, continuez à expérimenter, et bientôt vous serez capable de lancer des sorts TypeScript comme un pro ! Jusqu'à la prochaine fois, bon codage !

Credits: Image by storyset