Bryan TCHAJIP
Retour au blog
TypeScript

TypeScript : dompter les génériques pour un code plus sûr

2 juin 20267 min de lecture
TypeScript : dompter les génériques pour un code plus sûr

Sans génériques, on a souvent le choix entre dupliquer du code pour chaque type, ou tout typer en any et perdre les vérifications du compilateur. Les génériques résolvent ce dilemme : ils décrivent une relation entre les types d'entrée et de sortie, sans figer le type exact.

Le principe, en une fonction

function identity<T>(value: T): T {
  return value;
}

const nombre = identity(42);       // T déduit comme number
const texte = identity("bonjour"); // T déduit comme string

T est un paramètre de type : TypeScript le déduit automatiquement depuis l'argument passé, et garantit que le type de retour correspond exactement au type d'entrée. Pas de any, pas de duplication.

Un cas concret : une fonction fetch typée

async function fetchJSON<T>(url: string): Promise<T> {
  const response = await fetch(url);
  return response.json() as Promise<T>;
}

type User = { id: number; name: string };

const user = await fetchJSON<User>("/api/user/1");
// user est typé comme User : user.name est vérifié à la compilation

Contraindre un générique avec extends

On peut restreindre les types acceptés avec extends, pour garder de la souplesse tout en imposant une forme minimale.

function getLength<T extends { length: number }>(item: T): number {
  return item.length;
}

getLength("hello");      // ok, string a .length
getLength([1, 2, 3]);    // ok, array a .length
getLength(42);            // erreur : number n'a pas .length

C'est exactement ce mécanisme qui alimente les types utilitaires natifs de TypeScript comme Partial<T>, Pick<T, K> ou Record<K, V> : des génériques bien conçus, réutilisés partout dans l'écosystème.

Une question sur cet article, ou envie d'échanger ?

Me contacter