TypeScript : des types au-dessus de JavaScript
Détection à la compilation, annotations, inférence.
Objectifs
À la fin de cette leçon, vous saurez :
- opposer typage dynamique et statique ;
- annoter et laisser inférer ;
- comprendre ce que TypeScript ajoute — et ne change pas.
Le problème du JS pur
function aire(largeur, hauteur) {
return largeur * hauteur;
}
aire("10", 20); // "1020" : concaténation silencieuse !
L'erreur existe à l'écriture mais n'éclate qu'à l'exécution — parfois en production, parfois rarement. TypeScript déplace la détection au moment de la compilation :
function aire(largeur: number, hauteur: number): number {
return largeur * hauteur;
}
aire("10", 20);
// Error: Argument of type 'string' is not assignable to parameter of type 'number'
Typage dynamique vs statique
Dynamique (JS) : les types vivent avec les VALEURS, vérifiés à l'exécution
Statique (TS) : les types sont VÉRIFIÉS AVANT exécution, sur le code
TS reste JavaScript à l'exécution : aucun type ne survit à la compilation. C'est un filet de sécurité au développement, pas une machine virtuelle différente.
Annotation vs inférence
let age: number = 20; // annotation explicite
const nom = "Paul"; // inférence : TS sait déjà "string"
function saluer(qui: string): string { // paramètres : annoter
return `Bonjour ${qui}`; // retour : souvent inféré
}
Convention pragmatique : annoter les signatures publiques (paramètres, retours d'API), laisser inférer les variables locales évidentes. Les annotations sont de la documentation vérifiée par le compilateur — impossible de devenir fausse.
Ce que ça apporte concrètement
- Erreurs avant l'exécution : typos sur les propriétés, arguments inversés, null oubliés.
- Autocomplétion fiable : votre éditeur connaît la forme exacte des objets.
- Refactoring sûr : renommer un champ met en rouge tous les usages cassés.
- Contrats entre fichiers : la signature EST la documentation.
Ce que ça ne change pas
- L'exécution reste JS : mêmes performances, mêmes sémantiques (
===, prototypes...). - Les types ne valident PAS les données entrantes (JSON reçu du réseau !) :
aset types déclarés ne contrôlent rien à l'exécution. La validation runtime (comme vos DTO validés) reste obligatoire — règle capitale qui reviendra au chapitre NestJS.
Exercice
- Annotez
creerTache(titre, fait)puis appelez-la mal : observez l'erreur AVANT exécution. - Trouvez dans votre code trois endroits où TS aurait attrapé un bug passé.
- Pourquoi un type déclaré suffit-il à tromper TS face à un JSON externe ?
Résumé
- TS = JS + vérification de types avant exécution ; zéro changement au runtime.
- Annoter les frontières, inférer le local.
- Types ≠ validation runtime : deux protections complémentaires.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 3. Un type décrit ce que VOUS promettez ; il n'inspecte pas la donnée réelle. const user = await r.json() as Utilisateur ment peut-être : si le serveur renvoie autre chose, TS ne le saura jamais. D'où : schémas de validation à l'exécution (class-validator, zod...) pour tout ce qui vient de l'extérieur.