En une phrase
TypeScript est un langage de programmation qui s'appuie sur JavaScript en y ajoutant un « système de types », qui est comme un correcteur grammatical pour vos données et qui attrape une énorme catégorie de bugs avant même que votre code ne s'exécute.
Le problème qu'il résout
Imaginez les débuts du web. JavaScript est né dans la précipitation (la légende dit en seulement 10 jours) pour rendre les pages web un peu plus interactives. Il a été conçu pour de petits scripts : animer un bouton, valider un formulaire. Il était dynamique, flexible et permissif. Cette permissivité était sa plus grande force et, à mesure que le web a mûri, sa plus grande faiblesse.
En JavaScript « vanilla », une variable peut être tout ce qu'elle veut. Elle peut commencer comme un nombre, être réassignée à une chaîne de caractères, puis devenir un objet, pour finalement finir en undefined.
let myThing = 123; // myThing est un nombre
myThing = "Hello world"; // Maintenant, c'est une chaîne de caractères
myThing = { id: 456 }; // Et maintenant, un objet
Pour un script de 20 lignes, ça passe. Pour une application de 200 000 lignes qui fait tourner un service énorme comme Google Maps ou Figma, c'est la recette du chaos. Les développeurs passaient le mauvais type de données à une fonction, ce qui menait à la fameuse erreur undefined is not a function au runtime — c'est-à-dire, sous les yeux d'un vrai utilisateur. Le refactoring de code était un cauchemar ; changez une fonction, et vous risquiez de casser dix autres parties de l'application sans le savoir avant qu'il ne soit trop tard.
Microsoft, confronté à ce problème précis avec ses projets JavaScript à grande échelle, a décidé de mettre un peu d'ordre dans ce chaos. En 2012, ils ont sorti TypeScript. Le but n'était pas de remplacer JavaScript, mais de l'améliorer. Il ajouterait une couche de sécurité et de prévisibilité par-dessus le langage que tout le monde connaissait déjà, le rendant apte aux applications massives et complexes que le web moderne exigeait.
Comment ça marche sous le capot
La magie de TypeScript opère avant que le code n'arrive au navigateur. Votre navigateur n'exécute pas de TypeScript ; il exécute du bon vieux JavaScript. Le rôle de TypeScript est d'agir comme un linter hyper-intelligent et proactif pendant le développement.
### TypeScript est un superset de JavaScript
C'est le concept le plus important à saisir. Un « superset » (ou sur-ensemble) signifie que tout code JavaScript valide est aussi du code TypeScript valide. Vous pouvez prendre un fichier .js, le renommer en .ts, et ça fonctionnera. TypeScript ne fait qu'ajouter une nouvelle syntaxe par-dessus JavaScript.
L'ajout principal, ce sont les annotations de type. Vous pouvez maintenant dire à TypeScript quel genre de données il doit s'attendre à recevoir.
// Ça, c'est du JavaScript pur
function getLength(someValue) {
return someValue.length;
}
// Ça, c'est du TypeScript
function getLengthTyped(someValue: string | any[]) {
return someValue.length;
}
Dans la version JavaScript, si vous appeliez getLength(42), vous obtiendriez une erreur au runtime, car le nombre 42 n'a pas de propriété length. Dans la version TypeScript, votre éditeur de code et le compilateur vous hurleraient dessus immédiatement, vous disant qu'un nombre n'est pas un argument valide. Le bug est attrapé avant même que vous n'enregistriez le fichier.
### Le processus de transpilation
Donc, si les navigateurs n'exécutent pas TypeScript, qu'advient-il de cette syntaxe supplémentaire ? Elle est effacée lors d'un processus appelé la transpilation.
La transpilation est un type spécifique de compilation : une conversion de source à source. Le compilateur TypeScript (un programme généralement appelé tsc) lit votre fichier .ts, vérifie les erreurs de type, puis crache un fichier .js tout propre que n'importe quel navigateur peut comprendre.
Voici un avant-après :
Entrée TypeScript (.ts)
function greet(person: string, date: Date): string {
return `Hello ${person}, today is ${date.toDateString()}!`;
}
Sortie JavaScript (.js)
function greet(person, date) {
return "Hello ".concat(person, ", today is ").concat(date.toDateString(), "!");
}
Remarquez comment les annotations de type (: string, : Date) ont complètement disparu. Le transpiler les a utilisées pour vérifier votre travail, puis les a jetées, ne laissant derrière lui que du JavaScript exécutable. Un playground TypeScript effectue cette étape de transpilation instantanément, directement dans votre navigateur, pour que vous puissiez voir le résultat en temps réel.
### Vérification et Inférence de Types
Le « cerveau » de TypeScript, c'est son vérificateur de types (type-checker). C'est la partie qui analyse votre code et valide que les types correspondent. Mais vous n'avez pas toujours besoin d'écrire les types vous-même. TypeScript est assez malin pour les deviner la plupart du temps grâce à un processus appelé l'inférence de type.
let name = "Alice"; // TypeScript infère que `name` est de type `string`
let age = 30; // TypeScript infère que `age` est de type `number`
// Si vous essayez ça, TypeScript lèvera une erreur :
// Type 'number' is not assignable to type 'string'.
name = 42;
Vous n'avez pas eu à écrire let name: string = "Alice". TypeScript a vu que vous assigniez une chaîne de caractères littérale et a correctement inféré le type. Cela garde votre code propre et lisible tout en vous offrant tous les avantages de la sécurité. Vous n'avez besoin d'ajouter des types explicites que lorsque TypeScript ne peut pas les deviner tout seul, comme pour les paramètres de fonction ou les variables vides.
Histoires vécues
### Le Grand Refactoring
Le produit phare d'une startup était un monolithe JavaScript tentaculaire. L'équipe de départ avait avancé vite et cassé des trucs, et maintenant la nouvelle équipe en payait le prix. Ils devaient refactoriser un module central qui gérait les permissions des utilisateurs. Le problème ? Personne n'était sûr de la forme que l'objet user était censé avoir. Avait-il user.isAdmin ou user.role === 'admin' ? Est-ce que user.id arrivait en tant que nombre ou chaîne de caractères ?
Chaque changement était un pari risqué. Ils ont décidé d'introduire TypeScript, fichier par fichier. Ils ont commencé par définir une interface User claire :
interface User {
id: number;
email: string;
role: 'admin' | 'editor' | 'viewer';
lastLogin: Date;
}
Soudain, leurs IDEs se sont illuminés comme un sapin de Noël, signalant chaque endroit du code où l'objet user était utilisé incorrectement. Une fonction essayait d'accéder à user.isAdmin, qui n'existait pas sur leur nouvelle interface. Une autre passait un ID en chaîne de caractères au lieu d'un nombre. Le refactoring est passé d'un jeu de devinettes terrifiant à un processus systématique et guidé.
Leçon : TypeScript transforme un refactoring chaotique en une tâche d'ingénierie sûre et prévisible en créant une source de vérité unique pour vos structures de données.
### Le bug fantôme de l'API
Une développeuse front-end construisait un dashboard qui affichait des données d'une API tierce. La documentation de l'API indiquait clairement que le prix d'un produit serait un nombre, comme 19.99. Elle a donc écrit son code TypeScript en conséquence : interface Product { name: string; price: number; }.
Son code a très bien fonctionné pendant des semaines, jusqu'au jour où un utilisateur a signalé que le calcul du « Total » affichait NaN (Not a Number). Après des heures de débogage, elle a découvert que pour un produit spécifique et rare, l'API renvoyait le prix sous forme de chaîne de caractères : "19.99". En JavaScript, 10 + "19.99" donne la chaîne "1019.99", ce qui cassait tous ses calculs par la suite.
Avec TypeScript, elle aurait pu intercepter ça à la source. En validant les données entrantes de l'API par rapport à son interface Product, la non-concordance de type aurait déclenché une erreur au moment même où la mauvaise donnée entrait dans son système, et non dix étapes plus tard en essayant de faire un calcul.
Leçon : TypeScript impose des contrats de données, rendant votre application résiliente aux changements inattendus ou aux erreurs provenant d'API externes.
Erreurs et pièges courants
- L'échappatoire
any: TypeScript a un type spécial appeléany, qui dit essentiellement au compilateur « fais-moi confiance, je sais ce que je fais » et désactive toute vérification de type pour cette variable. Abuser deany, c'est comme acheter une voiture pour ses dispositifs de sécurité et les désactiver tous. Ça va à l'encontre de l'objectif même de TypeScript. - Ignorer les erreurs du compilateur : Parfois, vous verrez une ligne rouge ondulée de TypeScript, mais le JavaScript transpilé semble fonctionner correctement. Il est tentant d'ignorer l'erreur. C'est un piège. L'erreur est un signe avant-coureur d'un bug potentiel au runtime. Écoutez votre compilateur ; il essaie de vous aider.
- Lutter contre le système de types : Les débutants sont souvent frustrés quand TypeScript ne les laisse pas faire quelque chose. Au lieu de chercher la bonne façon de typer leur code, ils essaient de tromper le compilateur avec des assertions de type (
as any) ou d'autres bidouilles. Cela signifie généralement que leur compréhension du flux de données est défaillante, et que le compilateur identifie correctement un problème. - Oublier les paquets
@types: De nombreuses bibliothèques JavaScript populaires n'incluent pas leurs propres définitions de type. La communauté TypeScript maintient un immense dépôt de ces définitions appelé DefinitelyTyped. Si vous utilisez une bibliothèque comme Lodash ou Express, vous devez souvent installer un paquet@types/lodashcorrespondant pour obtenir une autocomplétion et une vérification de type adéquates.
Pourquoi vous devriez vous y intéresser
Vous devriez vous tourner vers TypeScript (ou au moins l'envisager) quand :
- Votre projet JavaScript dépasse la poignée de fichiers.
- Vous travaillez en équipe et avez besoin de vous assurer que tout le monde est sur la même longueur d'onde concernant les structures de données.
- Vous passez plus de temps à déboguer des erreurs
undefinedqu'à écrire de nouvelles fonctionnalités. - Vous voulez que votre éditeur de code devienne un assistant surpuissant, offrant une autocomplétion incroyable, des outils de refactoring et des messages d'erreur en direct.
- Vous construisez une application qui doit être maintenue et évoluer sur le long terme.
En bref, TypeScript est le standard professionnel pour le développement JavaScript moderne. L'apprendre est un investissement qui s'amortit de lui-même grâce à moins de bugs, une collaboration plus facile et une expérience de développement plus sereine.
Pour aller plus loin
- Site officiel et manuel de TypeScript: La source de vérité. Le manuel est un excellent guide, très complet.
- TypeScript sur Wikipédia: Pour un aperçu de haut niveau de son histoire, sa conception et ses fonctionnalités.
- MDN: Comprendre TypeScript: Le point de vue de Mozilla sur la place de TypeScript dans l'écosystème du développement web.
- DefinitelyTyped: Le dépôt de toutes les définitions de type tierces qui rendent l'écosystème TypeScript si riche.
- TypeScript Deep Dive: Un livre en ligne fantastique et approfondi qui couvre tout, des bases aux concepts avancés.
Comment un éditeur comprend le code
Les couleurs viennent d’un analyseur de langage, pas de l’exécution du programme. CodeMirror et Lezer reconnaissent les symboles et la structure dans le navigateur. Les suggestions combinent mots-clés, noms locaux lorsque disponibles, extraits et une petite référence intégrée ; survoler un symbole documenté révèle sa signature. Une suggestion ne garantit pas que cette API existe dans le moteur. Les diagnostics repèrent la syntaxe incorrecte lorsque l’analyseur le permet, sans remplacer le contrôle des types ni l’exécution : une syntaxe valide peut encore échouer. Ruby et Lua utilisent des modes fondés sur les tokens, aux diagnostics plus limités. Aucun serveur de langage distant : le code reste sur l’appareil.
CodeMirror & Lezer: MIT.