TypeScript - Interfaces Génériques
Salut là, futur superstar du codage ! Aujourd'hui, nous allons entreprendre un voyage passionnant dans le monde de TypeScript et explorer une de ses fonctionnalités les plus puissantes : les Interfaces Génériques. Ne vous inquiétez pas si vous êtes nouveau dans la programmation - je serai votre guide amical, et nous avancerons pas à pas. À la fin de cette leçon, vous serez étonné de voir combien vous avez appris !
Quelles sont les Interfaces Génériques ?
Avant de plonger dans les interfaces génériques, récapitulons rapidement ce que sont les interfaces dans TypeScript. Une interface est comme un contrat qui définit la structure d'un objet. Elle nous indique quelles propriétés et méthodes un objet devrait avoir.
Maintenant, imaginez si nous pouvions rendre ces interfaces plus flexibles, capables de travailler avec différents types de données. C'est là que les interfaces génériques entrent en jeu ! Elles nous permettent de créer des interfaces qui peuvent s'adapter à divers types de données, rendant notre code plus réutilisable et polyvalent.
Interface Générique de Base
Commençons avec un exemple simple :
interface Box<T> {
contents: T;
}
let numberBox: Box<number> = { contents: 42 };
let stringBox: Box<string> = { contents: "Hello, TypeScript!" };
Dans cet exemple, Box
est une interface générique. Le <T>
est comme un placeholder pour un type que nous spécifierons plus tard. Nous pouvons utiliser cette interface pour créer des boîtes qui peuvent contenir différents types d'items :
-
numberBox
est uneBox
qui contient un nombre. -
stringBox
est uneBox
qui contient une chaîne de caractères.
C'est pas génial ? C'est comme avoir une boîte magique qui peut s'adapter pour contenir ce que nous y mettons !
Plusieurs Paramètres de Type
Les interfaces génériques peuvent avoir plus d'un paramètre de type. regardons un exemple :
interface Pair<T, U> {
first: T;
second: U;
}
let pair1: Pair<number, string> = { first: 1, second: "one" };
let pair2: Pair<boolean, Date> = { first: true, second: new Date() };
Ici, Pair
est une interface générique avec deux paramètres de type, T
et U
. Cela nous permet de créer des paires d'items où chaque item peut être d'un type différent. C'est comme créer un duo dynamique de n'importe quelles deux types que nous voulons !
Interfaces Génériques avec des Méthodes
Les interfaces peuvent également inclure des méthodes, et ces méthodes peuvent utiliser les types génériques. Voici un exemple :
interface Reversible<T> {
data: T[];
reverse(): T[];
}
class NumberArray implements Reversible<number> {
constructor(public data: number[]) {}
reverse(): number[] {
return this.data.slice().reverse();
}
}
let numbers = new NumberArray([1, 2, 3, 4, 5]);
console.log(numbers.reverse()); // Output: [5, 4, 3, 2, 1]
Dans cet exemple, Reversible
est une interface générique qui inclut une méthode reverse()
. La classe NumberArray
implémente cette interface pour les nombres. La beauté de cette approche est que nous pourrions facilement créer des classes similaires pour des chaînes, des objets, ou tout autre type !
Interface Générique comme Type de Fonction
Maintenant, explorons comment nous pouvons utiliser des interfaces génériques pour décrire des types de fonction. C'est là que les choses deviennent vraiment intéressantes !
interface Transformer<T, U> {
(input: T): U;
}
let stringToNumber: Transformer<string, number> = (input) => parseInt(input);
console.log(stringToNumber("42")); // Output: 42
Dans cet exemple, Transformer
est une interface générique qui décrit une fonction. Elle prend un input de type T
et renvoie une valeur de type U
. Nous créons ensuite une fonction stringToNumber
qui transforme une chaîne en nombre en utilisant cette interface.
Exemple du Monde Réel : Processeur de Données
Regardons un exemple plus complexe que vous pourriez rencontrer dans la programmation réelle :
interface DataProcessor<T, U> {
processItem(item: T): U;
processArray(items: T[]): U[];
}
class StringToNumberProcessor implements DataProcessor<string, number> {
processItem(item: string): number {
return parseInt(item);
}
processArray(items: string[]): number[] {
return items.map(item => this.processItem(item));
}
}
let processor = new StringToNumberProcessor();
console.log(processor.processItem("42")); // Output: 42
console.log(processor.processArray(["1", "2", "3"])); // Output: [1, 2, 3]
Dans cet exemple, nous définissons une interface DataProcessor
qui peut traiter des items individuels ou des arrays d'items. La classe StringToNumberProcessor
implémente cette interface pour convertir des chaînes en nombres. Ce patron est incroyablement utile lorsque vous avez besoin de traiter des données de diverses manières tout en conservant la sécurité des types.
Conclusion
Félicitations ! Vous avez fait un grand pas dans votre voyage TypeScript en apprenant sur les interfaces génériques. Ces outils puissants nous permettent d'écrire du code flexible et réutilisable qui peut travailler avec différents types de données. Souvenez-vous, la pratique rend parfait, donc n'ayez pas peur d'expérimenter avec ces concepts dans vos propres projets.
Voici un tableau de référence rapide des méthodes que nous avons couvertes :
Méthode | Description |
---|---|
interface Box<T> |
Crée une interface générique pour une boîte qui peut contenir n'importe quel type |
interface Pair<T, U> |
Crée une interface générique pour une paire d'items de types différents |
interface Reversible<T> |
Crée une interface générique avec une méthode pour inverser un array |
interface Transformer<T, U> |
Crée une interface générique pour une fonction qui transforme un type en un autre |
interface DataProcessor<T, U> |
Crée une interface générique pour traiter des items individuels ou des arrays d'items |
Continuez à coder, continuez à apprendre, et souvenez-vous - dans le monde de TypeScript, les génériques sont votre superpouvoir ! ?♀️?♂️
Credits: Image by storyset