83 conseils concrets pour passer de « ça compile » à « je maîtrise le système de types ».
Pourquoi ce livre
TypeScript a un problème de réputation inversé : tout le monde l'utilise, presque personne ne le comprend. On annote jusqu'à ce que le rouge disparaisse, on dégaine un as ou un any quand le compilateur résiste, et on appelle ça « faire du TypeScript ». Le code compile, mais chaque erreur de type reste une négociation au jugé.
Vanderkam a écrit ce qu'il appelle lui-même un « standard second book » : pas un manuel pour débuter, un livre pour passer d'utilisateur à expert. La méthode, héritée des Effective C++ et Effective Java : 83 items courts, chacun une règle actionnable ; et il l'assume dès la préface : « là où un livre de référence explique les cinq façons de faire X, un livre Effective vous dit laquelle des cinq utiliser, et pourquoi » (1re éd., p. xi-xii). La 2e édition (mai 2024) ajoute deux chapitres entiers, dont la programmation au niveau des types.
Les idées qui restent
1TypeScript modélise JavaScript, défauts compris
Pourquoi const x = 2 + '3' ne déclenche-t-il aucune erreur ? Parce que c'est du JavaScript valide (résultat : la string "23"), et que le système de types de TypeScript « modélise le comportement de JavaScript à l'exécution » (1re éd., p. 5). TS n'est pas là pour corriger JS, il est là pour le décrire. Et Vanderkam pose l'aveu fondateur dès l'item 1 : ce système de types « n'est résolument pas sound, et n'a jamais eu vocation à l'être » ; comprenez : le type affiché peut mentir à l'exécution, c'est un compromis assumé. « Si la soundness compte pour vous, regardez plutôt des langages comme Reason ou Elm » (1re éd., p. 5). Accepter ce compromis, c'est comprendre 80 % des comportements « bizarres » du langage.
2Un type est un ensemble de valeurs, tout le reste en découle
Le modèle mental central du livre (item 7) : chaque type est l'ensemble des valeurs qu'il admet. never est l'ensemble vide, un type littéral "x" est un singleton, A | B est une union d'ensembles, A & B une intersection. Et la règle qui démine les messages d'erreur les plus cryptiques : traitez « extends », « assignable à » et « sous-type de » comme des synonymes de « sous-ensemble de » (item 7). Le paradoxe le plus classique s'éclaire d'un coup : A & B intersecte les valeurs, pas les propriétés. Moins de valeurs admissibles (chacune doit satisfaire les deux contraintes), donc plus de propriétés garanties : l'union des membres. Symétriquement, sur A | B seules les propriétés communes sont accessibles avant narrowing. Le livre le condense en deux formules : keyof (A&B) = (keyof A) | (keyof B) et keyof (A|B) = (keyof A) & (keyof B) (item 7). Plus de contraintes, moins de valeurs, plus de propriétés garanties. Même logique : Vector3D est un sous-ensemble de Vector2D (plus de propriétés = domaine plus restreint), et le extends des génériques ne parle pas d'héritage mais de sous-ensembles.
3Les types s'évaporent à l'exécution
tsc fait deux métiers indépendants : vérifier les types et générer du JS. Indépendants au point que « les types de votre code ne peuvent pas affecter le JavaScript que TypeScript émet », et donc « ne peuvent pas affecter la façon dont votre code s'exécute » (1re éd., p. 10). Trois pièges concrets en découlent : instanceof Rectangle échoue si Rectangle est une interface (effacée à la compilation, il faut un tagged union ou une class) ; as number ne convertit RIEN au runtime ; et du code avec des erreurs de type peut quand même produire du JS qui tourne. Quiconque a déjà cherché pourquoi son as ne « marchait pas » a payé pour apprendre cet item.
4Le typage est structurel, et vos types sont ouverts
JavaScript est « duck typed par nature » (1re éd., p. 15) et TypeScript suit : si l'objet a les bonnes propriétés, il passe, peu importe comment il a été construit. L'exemple du livre : une fonction qui attend un Vector2D accepte sans broncher un Vector3D, la composante z est silencieusement ignorée. « Que ça vous plaise ou non, vos types sont "ouverts" » : impossible de sceller un type. Ce n'est pas un bug, c'est le modèle de JS ; mais ça explique pourquoi Object.keys vous renvoie du string et pas du keyof T.
5Un bon type rend les états invalides impossibles à écrire
L'exemple qui reste : le crash du vol Air France 447. Les deux sticks de l'Airbus étaient indépendants, l'avion faisait la moyenne des deux entrées ; un pilote tirait, l'autre poussait, et le système acceptait cet état contradictoire (1re éd., ch. 4). Le livre le modélise en TypeScript, avant et après :
// ✗ Le 447 : deux sticks indépendants, l'état contradictoire est représentable interface CockpitControls { leftSideStick: number; // 0 = neutre, + = en avant rightSideStick: number; // peut dire l'inverse du premier… } // ✓ Des commandes liées mécaniquement : impossible de se contredire interface CockpitControls { stickAngle: number; // plus besoin de getStickSetting() }
Avec deux champs, toute fonction getStickSetting doit choisir quel stick croire, et toutes les stratégies du livre (faire confiance au pilote, prendre la moyenne…) échouent. Avec un seul champ, « nos organigrammes deviennent évidents : vous n'avez plus besoin de getStickSetting du tout » (1re éd., ch. 4). Côté web, c'est l'interface State { isLoading: boolean; error?: string } qui admet « en chargement ET en erreur » : la tagged union Pending | Error | Success rend la contradiction inexprimable. Le « Thing to Remember » officiel : « préférez les types qui ne représentent que des états valides ; même s'ils sont plus longs ou plus pénibles à exprimer, ils vous épargneront du temps et de la souffrance » (item 29).
6any est contagieux, unknown est l'antidote
Un any retourné par une fonction contamine silencieusement tous ses appelants : plus d'autocomplétion, plus de vérification au refactoring, et des bugs masqués. Le verdict de Vanderkam est cruel : « du TypeScript truffé d'any peut être plus pénible à manier que du JavaScript non typé » (1re éd., p. 24), parce qu'on paye le coût des types sans la protection. L'antidote : unknown, le type « je ne sais pas encore », qui force à vérifier avant d'utiliser. Le fil rouge du livre pour l'illustrer : parseYAML et les romans des sœurs Brontë.
const book = parseYAML(` name: Jane Eyre author: Charlotte Brontë `); console.log(book.title); // aucune erreur, loggue "undefined" au runtime book('read'); // aucune erreur, plante : "book is not a function"
Avec unknown en type de retour, ces deux lignes refusent de compiler tant qu'on n'a pas prouvé ce qu'est book (item 46).
7Les génériques sont des fonctions entre types (le chapitre qui justifie la 2e édition)
Le chapitre 6, inédit, donne enfin un cadre au TypeScript « de niveau type » : « pensez les types génériques comme des fonctions entre types » (item 50). MyPick<T, K> prend deux types et en retourne un troisième, exactement comme une fonction. Sa règle d'or tient en une phrase : un paramètre de type doit apparaître au moins deux fois pour établir une relation ; sinon il ne relie rien et ment (l'anti-pattern parseYAML<T> qui « retourne » le type qu'on lui demande sans rien vérifier, item 51). Le chapitre couvre les template literal types (un querySelector qui comprend "button#id"), les types récursifs, et même les tests de types. Avec un garde-fou rare dans ce genre de chapitre : « le TypeScript de niveau type est un outil d'une puissance impressionnante, mais pas toujours le bon outil pour la tâche » (item 58) ; au-delà d'un seuil de complexité, générez les types depuis la source (codegen) au lieu de les calculer.
8Migrer : dans l'ordre, et noImplicitAny en dernier
Le dernier chapitre est un récit d'expérience : Vanderkam a migré dygraphs, sa bibliothèque de graphes vieillissante, et en tire un ordre de bataille. Moderniser le JS d'abord, activer allowJs, migrer module par module en remontant le graphe de dépendances (les feuilles d'abord, les tests en dernier), résister à l'envie de refactorer en route, et n'activer noImplicitAny qu'à la toute fin. Les chiffres qui motivent, tirés des études que le chapitre cite : 15 % des bugs corrigés dans les projets JavaScript de GitHub auraient pu être évités avec TypeScript, et 38 % des postmortems d'AirBnb.
Trois choses que je ne savais pas avant de le lire
- Les données d'exemple du livre sont les romans des sœurs Brontë : Wuthering Heights (Emily), Jane Eyre (Charlotte), The Tenant of Wildfell Hall (Anne), une sœur par variante de
parseYAML(items 46, 51). - Vanderkam avoue dans la préface lire les livres techniques « en regardant les exemples et en survolant la prose », et avoir écrit le sien en conséquence : les exemples de code se suffisent (1re éd., p. xii).
- Tout le squelette du livre est public : le repo officiel github.com/danvk/effective-typescript contient les 83 items avec leurs résumés « Things to Remember » et chaque exemple en playground TypeScript exécutable.
Mon avis, honnêtement
La plupart des livres de conseils empilent des astuces sans lien entre elles. Celui-là, non. Les 83 items racontent la même histoire : comment le vérificateur de types raisonne. Une fois l'item 7 digéré (un type est un ensemble de valeurs), les messages d'erreur de TypeScript cessent d'être du bruit : on les lit comme des phrases. Autre qualité rare : le livre ne survend pas son propre langage. Il dit franchement que TypeScript laisse passer certaines erreurs (c'est un choix de conception), et qu'au-delà d'un certain point, compliquer ses types fait plus de mal que de bien.
Les réserves, maintenant. Le chapitre 6 apprend à écrire des types qui calculent d'autres types. C'est nécessaire et bien fait, mais c'est de la gymnastique : 90 % des devs ne la pratiqueront jamais eux-mêmes, des bibliothèques comme Zod ou tRPC le font à leur place. Quelques items relèvent du bon sens bien emballé. Et c'est un vrai livre de deuxième étape : sans six mois de TypeScript derrière soi, les trois quarts des items répondent à des questions qu'on ne s'est pas encore posées.
En 2026, ce livre a trouvé un second métier que Vanderkam n'avait pas prévu : relire le code généré par IA. L'IA produit du TypeScript qui compile, mais truffé de as posés pour faire taire le compilateur, de génériques qui ne relient rien, et d'états contradictoires permis par des types trop vagues. Les items 5, 9, 29 et 51 décrivent exactement ces défauts. Lire ce livre, c'est apprendre à relire la machine.
Odilon
Toujours valable en 2026 ?
C'est la 2e édition (mai 2024, TypeScript 5) qui est résumée ici : satisfies, template literal types et types récursifs sont couverts. Rien dans les versions sorties depuis n'invalide un item : le livre enseigne le système de types, pas l'outillage.
Pour qui ?
Lisez-le si
- Vous écrivez du TypeScript depuis 6 mois à 2 ans et les erreurs du compilateur restent des négociations au jugé
- Votre codebase accumule les
anyet lesasposés « pour que ça compile » - Vous relisez du TypeScript généré par IA et voulez repérer les types menteurs
- Vous préparez une migration JS → TS : le dernier chapitre est un plan de bataille éprouvé
Passez si
- Vous débutez : le handbook officiel et un vrai projet d'abord, ce livre dans un an
- Vous ne faites pas de TypeScript et n'y êtes pas contraint : tout ici est spécifique au langage
- Vous attendez un cours structuré : c'est un recueil de 83 essais, pas une progression pédagogique
Pour aller plus loin
Pratiquez avec le cours TypeScript de ce site (un vrai compilateur TS tourne dans votre navigateur), et le cours JS avancé pour le socle. Et Fluent Python joue exactement le même rôle côté Python, aussi dans cette bibliothèque.
Commentaires (0)