Generics en TypeScript : guide complet sur les génériques

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course
```html

Introduction aux Generics en TypeScript



TypeScript est un langage fortement typé qui étend les capacités de JavaScript en ajoutant un typage statique. Cependant, l'une de ses fonctionnalités les plus puissantes et flexibles est le mécanisme Generics (génériques). Si vous avez déjà écrit du code qui doit fonctionner avec différents types de données tout en préservant la sécurité des types, alors les Generics sont exactement ce qu'il vous faut.



Imaginez que vous créez une fonction universelle qui peut accepter des tableaux de nombres, de chaînes de caractères ou d'objets. Sans les génériques, vous devriez soit utiliser le type any (ce qui annule tous les avantages de TypeScript), soit écrire des fonctions séparées pour chaque type. Les Generics résolvent ce problème de manière élégante et sécurisée. Dans cet article, nous allons voir ce que sont les Generics, pourquoi ils sont nécessaires et comment les utiliser efficacement dans des projets réels.



Que sont les Generics et pourquoi en avons-nous besoin ?



Generics est un mécanisme qui permet de créer des composants (fonctions, classes, interfaces) capables de fonctionner avec différents types de données sans perdre l'information sur ces types. Au lieu de fixer un type spécifique, vous utilisez un paramètre de type qui est substitué au moment de l'appel.



Le problème sans Generics



Supposons que vous souhaitiez écrire une fonction qui retourne le premier élément d'un tableau. Sans les génériques, cela pourrait ressembler à ceci :



function getFirstElement(arr: any[]): any {  return arr[0];}

const num = getFirstElement([1, 2, 3]); // Type 'any' — nous avons perdu l'informationconsole.log(num.toUpperCase()); // Erreur à l'exécution, mais TypeScript ne dit rien


Ici, nous utilisons any, et TypeScript ne peut pas nous avertir que num est un nombre et non une chaîne de caractères. Cela conduit à des erreurs potentielles lors de l'exécution.



La solution avec les Generics



Réécrivons maintenant la même fonction en utilisant les génériques :



function getFirstElement<T>(arr: T[]): T {  return arr[0];}

const num = getFirstElement([1, 2, 3]); // Type 'number'const str = getFirstElement(['a', 'b', 'c']); // Type 'string'

// num.toUpperCase(); // Erreur de compilation — TypeScript sait que num est un nombre


Le symbole <T> est le paramètre de type. Il agit comme un placeholder : lorsque nous appelons la fonction avec un tableau de nombres, T devient number, et la valeur retournée reçoit également le type number. Ainsi, nous préservons un typage strict sans perdre en flexibilité.



Comment utiliser les Generics : scénarios principaux



Les Generics ne s'appliquent pas seulement aux fonctions, mais aussi aux classes, interfaces et types. Examinons les scénarios les plus courants.



Generics dans les fonctions



Le cas le plus simple et le plus fréquent concerne les fonctions qui travaillent avec des données de différents types. Par exemple, une fonction pour créer une paire clé-valeur :



function createPair<K, V>(key: K, value: V): { key: K; value: V } {  return { key, value };}

const pair = createPair('id', 123); // { key: string; value: number }console.log(pair.key.toUpperCase()); // Fonctionne// pair.key.toFixed(); // Erreur — key est une chaîne de caractères


Ici, nous utilisons deux paramètres de type : K pour la clé et V pour la valeur. TypeScript déduit automatiquement les types en fonction des arguments.



Generics dans les classes



Les génériques sont parfaits pour créer des classes universelles, comme des piles, des files d'attente ou des magasins de données :



class Stack<T> {  private items: T[] = [];

push(item: T): void { this.items.push(item); }

pop(): T | undefined { return this.items.pop(); }

peek(): T | undefined { return this.items[this.items.length - 1]; }}

const numberStack = new Stack<number>();numberStack.push(10);numberStack.push(20);console.log(numberStack ```

Blogs

Book Recommendations