Présentation

TypeScript est un langage de programmation construit au-dessus de JavaScript qui ajoute principalement un système de types statiques et des outils d’analyse destinés à rendre les grandes bases de code plus prévisibles et plus faciles à maintenir.

Un fichier TypeScript peut utiliser pratiquement toute la syntaxe JavaScript habituelle, puis y ajouter des annotations de types, interfaces, generics, unions, types conditionnels et de nombreuses autres constructions destinées au compilateur. Après vérification, ces informations de types sont généralement supprimées et le code est transformé en JavaScript standard destiné au navigateur, à Node.js ou à un autre environnement compatible.

TypeScript ne remplace donc pas JavaScript à l’exécution. Le navigateur n’exécute généralement pas les interfaces, aliases de types ou generics TypeScript : il exécute le JavaScript produit après compilation ou transformation.

L’intérêt principal intervient avant cette exécution. Le compilateur peut détecter qu’une propriété n’existe pas, qu’une fonction reçoit un argument incompatible, qu’une valeur peut être undefined ou qu’un changement de structure provoque des erreurs ailleurs dans le projet.

Ces informations servent également aux éditeurs de code. Autocomplétion, navigation vers une définition, recherche de références, renommage, documentation contextuelle et nombreux refactorings peuvent exploiter le système de types pour mieux comprendre le programme.

TypeScript a été créé par Microsoft et publié pour la première fois en 2012. Le projet est open source sous licence Apache 2.0 et son écosystème dépasse largement les outils Microsoft : React, Angular, Vue, Svelte, Node.js, Deno, Bun et de nombreuses bibliothèques JavaScript l’utilisent ou fournissent directement leurs types.

La génération actuelle marque également un changement technique majeur. TypeScript 7 utilise désormais un port natif du compilateur et de l’outillage écrit en Go, destiné à remplacer progressivement l’ancienne implémentation elle-même écrite en TypeScript. Microsoft annonce des gains généralement compris entre environ 8x et 12x sur les builds complets, selon les projets.

Lors de cette vérification, la version stable publiée la plus récente est TypeScript 7.0.2, sortie le 20 août 2026.

Fonctionnalités

Ajouter des types sans abandonner JavaScript

TypeScript est souvent présenté comme un superset de JavaScript.

Un grand nombre de fichiers JavaScript valides peuvent donc être repris progressivement puis enrichis avec des informations de type.

Par exemple, une fonction peut préciser que deux paramètres attendent des nombres et qu’elle retourne un nombre. Le compilateur peut ensuite signaler un appel qui lui transmet une chaîne de caractères.

Les types disparaissent normalement lors de la génération du JavaScript.

Cette caractéristique distingue TypeScript d’un langage possédant son propre runtime : les types servent avant tout à analyser le programme pendant le développement, pas à modifier directement le comportement des valeurs pendant l’exécution.

Inférence de types

Il n’est pas nécessaire d’annoter chaque variable manuellement.

TypeScript utilise largement l’inférence de types pour déduire des informations à partir du code.

Si une variable est initialisée avec un nombre, le compilateur peut déterminer automatiquement qu’elle contient un number. Il peut également déduire le type de retour de nombreuses fonctions ou le paramètre générique correspondant à un argument.

Cette inférence permet de conserver du code relativement léger tout en bénéficiant d’un contrôle statique.

L’objectif n’est donc pas de transformer chaque ligne en déclaration de type, mais d’ajouter des annotations lorsque le compilateur ne peut pas déterminer correctement l’intention du développeur ou lorsqu’une API publique mérite d’être explicitement documentée.

Types primitifs, tableaux et objets

TypeScript reprend les types correspondant aux principales valeurs JavaScript :

  • string ;
  • number ;
  • boolean ;
  • bigint ;
  • symbol ;
  • null ;
  • undefined.

Il ajoute également une syntaxe permettant de décrire précisément tableaux, tuples, objets et fonctions.

Un objet peut par exemple être décrit comme possédant un nom obligatoire, un âge optionnel et une méthode particulière.

Les tuples permettent de représenter une séquence dont chaque position possède un type connu, contrairement à un tableau homogène classique.

TypeScript sait également conserver des valeurs littérales comme types, par exemple "draft" | "published" plutôt qu’un simple string.

Interfaces et aliases de types

Les interfaces permettent de décrire la forme attendue d’un objet.

Elles sont fréquemment utilisées pour définir les propriétés d’un composant, la structure d’un utilisateur, la configuration d’une fonction ou un contrat partagé entre plusieurs parties d’une application.

Les type aliases permettent eux aussi de nommer des types, mais peuvent représenter des constructions plus variées : unions, intersections, primitives, tuples ou combinaisons complexes.

Interfaces et aliases se recoupent sur plusieurs usages mais ne sont pas totalement équivalents.

Les interfaces disposent notamment d’un système de déclaration fusionnée particulièrement utile dans certains scénarios d’extension de bibliothèques.

Typage structurel

TypeScript utilise principalement un système de typage structurel.

Cela signifie que la compatibilité dépend surtout de la forme d’une valeur plutôt que de son appartenance explicite à une classe ou une hiérarchie particulière.

Si une fonction attend un objet possédant name: string, n’importe quel objet ayant au moins cette propriété compatible peut généralement être accepté, même s’il n’a jamais déclaré qu’il implémentait une interface précise.

Cette philosophie correspond assez naturellement au fonctionnement flexible de JavaScript.

Elle diffère cependant des systèmes nominaux utilisés par certains autres langages, où deux types portant la même structure peuvent rester incompatibles s’ils n’appartiennent pas explicitement à la même hiérarchie.

Unions et intersections

Les union types permettent d’indiquer qu’une valeur peut appartenir à plusieurs catégories.

Un identifiant peut par exemple être défini comme string | number.

Le code doit ensuite tenir compte de ces différentes possibilités avant d’utiliser une fonction propre à l’un des types.

Les intersection types combinent au contraire plusieurs types afin de construire une valeur qui respecte simultanément plusieurs contrats.

Ces mécanismes permettent de modéliser de nombreux états applicatifs sans devoir créer systématiquement de nouvelles classes.

Narrowing et analyse du flux de contrôle

TypeScript analyse les conditions du programme pour réduire progressivement les types possibles.

Si une variable possède le type string | undefined, un test vérifiant qu’elle n’est pas undefined permet au compilateur de la considérer ensuite comme une chaîne dans la branche correspondante.

Ce narrowing fonctionne avec plusieurs mécanismes JavaScript :

  • typeof ;
  • instanceof ;
  • comparaisons ;
  • propriété in ;
  • vérifications de vérité ;
  • discriminants d’objets ;
  • fonctions de garde de type.

Cette analyse du flux de contrôle constitue l’une des fonctions les plus importantes de TypeScript, car elle permet d’obtenir un typage précis sans multiplier les conversions explicites.

Generics

Les generics permettent de créer des composants dont les types restent paramétrables.

Une fonction peut par exemple accepter une valeur de type T et retourner le même type T sans perdre l’information précise sur cette valeur.

Contrairement à any, un generic conserve le lien entre les différents emplacements où le type apparaît.

Les generics sont utilisés dans les fonctions, interfaces, classes, collections et bibliothèques.

Ils peuvent être associés à des contraintes, des valeurs par défaut et des relations entre plusieurs paramètres de type.

Cette capacité constitue une base importante des API TypeScript avancées.

Types conditionnels, mapped types et keyof

Le système de types TypeScript permet de construire de nouveaux types à partir de types existants.

keyof produit par exemple l’union des clés connues d’un objet.

Les mapped types permettent de parcourir ces clés afin de transformer chaque propriété.

Les conditional types choisissent un type en fonction d’une condition portant sur un autre type.

Ils peuvent être combinés avec infer afin d’extraire certaines informations d’un type complexe.

Ces fonctions rendent possible la création de bibliothèques extrêmement flexibles, mais peuvent aussi produire des définitions difficiles à comprendre lorsqu’elles sont utilisées de manière excessive.

Utility Types intégrés

TypeScript fournit plusieurs utility types destinés à réaliser des transformations courantes.

Parmi les plus utilisés :

  • Partial<T> ;
  • Required<T> ;
  • Readonly<T> ;
  • Pick<T, K> ;
  • Omit<T, K> ;
  • Record<K, T> ;
  • Exclude<T, U> ;
  • Extract<T, U> ;
  • ReturnType<T> ;
  • Parameters<T> ;
  • Awaited<T> ;
  • NonNullable<T>.

Ils permettent par exemple de rendre toutes les propriétés optionnelles, sélectionner seulement certains champs ou extraire le type retourné par une fonction.

Ces utilitaires évitent de réécrire constamment les mêmes transformations.

unknown, any et never

TypeScript propose plusieurs types particuliers destinés à gérer les situations où les informations sont incomplètes ou impossibles.

any désactive largement la vérification pour une valeur et permet presque toutes les opérations. Il facilite certaines migrations mais réduit fortement la protection apportée par TypeScript.

unknown représente également une valeur inconnue, mais oblige le programme à vérifier son type avant de l’utiliser.

never décrit une valeur qui ne peut pas exister, par exemple le retour d’une fonction qui lève systématiquement une erreur ou certaines branches devenues impossibles après narrowing.

Une base de code stricte privilégie généralement unknown lorsque la valeur est réellement inconnue plutôt que d’utiliser systématiquement any.

Classes et modificateurs propres à TypeScript

TypeScript reprend les classes JavaScript et ajoute des contrôles supplémentaires.

Les paramètres et propriétés peuvent recevoir des annotations de type.

Le langage fournit également des modificateurs comme :

  • public ;
  • private ;
  • protected ;
  • readonly ;
  • abstract.

Certains de ces mécanismes n’ont pas exactement le même rôle que les champs privés JavaScript utilisant #.

Les modificateurs TypeScript sont principalement vérifiés pendant la compilation, tandis que les champs privés JavaScript possèdent une véritable sémantique d’encapsulation à l’exécution.

Cette distinction devient importante lorsqu’un développeur dépend réellement de la confidentialité d’une propriété au runtime.

Enums et autres constructions spécifiques

TypeScript possède également certaines constructions qui ne correspondent pas simplement à une annotation supprimée.

Les enums peuvent générer du JavaScript supplémentaire afin de créer un objet utilisable à l’exécution.

Les projets modernes utilisent parfois à la place des unions de valeurs littérales ou des objets as const, notamment pour rester plus proches du JavaScript standard.

TypeScript propose également des namespaces et plusieurs fonctions historiques, mais certaines approches anciennes sont progressivement moins recommandées à mesure que JavaScript lui-même fournit davantage de primitives standardisées.

Compilation vers JavaScript

Le compilateur TypeScript, tsc, analyse les fichiers .ts et .tsx, vérifie les types puis peut produire du JavaScript.

La version d’ECMAScript ciblée est configurable.

Un projet peut par exemple produire du JavaScript relativement moderne pour un environnement récent ou transformer certaines syntaxes afin de viser un runtime plus ancien.

Il est important de distinguer transformation syntaxique et polyfill.

TypeScript peut convertir certaines syntaxes récentes vers une forme plus ancienne, mais il n’ajoute pas automatiquement toutes les API absentes d’un vieux navigateur. Une fonction moderne inexistante dans l’environnement cible peut nécessiter un polyfill séparé.

TypeScript 7 et nouveau compilateur natif

TypeScript 7 représente l’un des plus importants changements d’architecture du projet.

L’ancienne implémentation du compilateur et du language service était historiquement écrite elle-même en TypeScript puis exécutée via JavaScript.

La nouvelle génération a été portée en Go.

Microsoft explique avoir conservé autant que possible la structure et la logique de l’implémentation précédente afin de maintenir la compatibilité des résultats tout en bénéficiant de code natif et du parallélisme en mémoire partagée.

Sur les builds complets, l’équipe TypeScript observe généralement des gains d’environ 8 à 12 fois, selon la taille et la structure du projet.

Cette amélioration concerne particulièrement les grandes bases de code, où les temps de compilation et d’analyse peuvent représenter une part importante du workflow quotidien.

TypeScript 6 reste disponible séparément pour les projets qui ont encore besoin de l’ancienne génération pendant la transition.

tsconfig.json pour configurer un projet

Un projet TypeScript est généralement défini par un fichier tsconfig.json.

Celui-ci indique quels fichiers appartiennent au projet et configure le comportement du compilateur.

Parmi les options importantes figurent notamment :

  • target ;
  • module ;
  • moduleResolution ;
  • lib ;
  • strict ;
  • jsx ;
  • outDir ;
  • rootDir ;
  • declaration ;
  • sourceMap ;
  • allowJs ;
  • checkJs.

Les projets monorepo ou applications complexes peuvent utiliser plusieurs fichiers tsconfig et des project references afin de séparer différentes parties du code.

Une configuration cohérente avec le runtime réel est essentielle : les réglages adaptés à une application Web empaquetée avec Vite ne sont pas nécessairement les mêmes que ceux d’un package npm ou d’un serveur Node.js.

Mode strict

L’option strict active un ensemble de contrôles destinés à rendre le système de types plus exigeant.

Elle inclut notamment des règles portant sur les valeurs nulles, les paramètres de fonctions ou les usages implicites de any.

strictNullChecks est particulièrement important.

Lorsqu’il est actif, null et undefined ne sont plus considérés comme automatiquement compatibles avec la plupart des autres types.

Une propriété éventuellement absente doit donc être traitée explicitement avant son utilisation.

Ce mode détecte davantage de problèmes mais peut demander plus de travail lors de la migration d’un ancien projet JavaScript ou TypeScript peu strict.

JavaScript existant avec allowJs et checkJs

Adopter TypeScript ne nécessite pas obligatoirement de convertir toute une base de code immédiatement.

L’option allowJs permet d’inclure des fichiers .js dans le projet.

checkJs demande au compilateur de signaler également certaines erreurs dans ces fichiers JavaScript.

Des annotations JSDoc peuvent fournir des informations de type sans changer l’extension du fichier.

Cette approche permet une migration progressive : commencer par analyser le JavaScript existant, ajouter des annotations là où elles sont utiles, puis convertir certains fichiers en .ts au fur et à mesure.

Fichiers de déclaration .d.ts

Les fichiers .d.ts décrivent les types d’un code JavaScript sans contenir son implémentation classique.

Une bibliothèque peut les publier afin que les utilisateurs TypeScript connaissent ses fonctions, classes, objets et signatures.

Certaines bibliothèques incluent directement leurs déclarations dans leur package.

Pour d’autres, la communauté fournit des définitions via DefinitelyTyped, généralement installées sous la forme @types/nom-du-package.

Ce mécanisme permet à TypeScript de comprendre une énorme partie de l’écosystème JavaScript, même lorsque la bibliothèque d’origine n’est pas elle-même écrite en TypeScript.

JSX et fichiers TSX

TypeScript prend en charge JSX grâce aux fichiers .tsx.

Le compilateur peut vérifier les propriétés transmises aux composants et transformer ou préserver la syntaxe JSX selon la configuration.

Plusieurs modes existent notamment pour React classique, le runtime JSX automatique ou React Native.

TypeScript est ainsi devenu extrêmement courant dans les projets React.

D’autres frameworks peuvent également utiliser JSX ou des systèmes de types liés à TypeScript selon leur propre toolchain.

Modules, ESM et CommonJS

TypeScript comprend différents systèmes de modules utilisés dans l’écosystème JavaScript.

Les projets modernes utilisent de plus en plus les ECMAScript Modules — ESM, avec import et export.

Node.js possède cependant un historique important autour de CommonJS.

Les bundlers comme Vite, webpack, Rollup ou esbuild peuvent également appliquer leurs propres règles de résolution et transformation.

TypeScript propose donc plusieurs stratégies de module et moduleResolution.

Une mauvaise configuration peut provoquer des différences entre ce que le compilateur pense pouvoir importer et ce que le runtime sait réellement charger.

La documentation recommande de choisir ces options en fonction de l’environnement d’exécution concret plutôt que d’utiliser une configuration universelle pour tous les projets.

Intégration IDE et Language Service

TypeScript ne se limite pas au compilateur en ligne de commande.

Son Language Service fournit aux éditeurs les informations nécessaires pour comprendre le projet en continu.

Cela permet notamment :

  • autocomplétion ;
  • affichage des types ;
  • navigation vers la définition ;
  • recherche de références ;
  • renommage de symboles ;
  • refactorings ;
  • diagnostics en temps réel ;
  • documentation contextuelle.

Visual Studio Code possède une intégration particulièrement poussée, mais TypeScript peut également être utilisé dans de nombreux autres éditeurs et IDE.

Ces fonctions représentent une partie essentielle de son intérêt, y compris dans des projets JavaScript qui n’utilisent pas encore pleinement le compilateur TypeScript.

Cas d’usage

Sécuriser une application JavaScript existante

Une équipe peut ajouter TypeScript progressivement à un projet JavaScript sans tout réécrire.

Elle peut commencer avec allowJs et checkJs, introduire des annotations JSDoc puis convertir les modules les plus importants en .ts.

Les erreurs liées aux propriétés absentes, paramètres incorrects ou valeurs potentiellement undefined apparaissent alors plus tôt dans le cycle de développement.

Cette migration progressive réduit le risque par rapport à une réécriture complète.

Construire une grande application front-end

Une application React, Vue, Angular ou Svelte possède souvent de nombreux composants, états, réponses API et objets partagés.

TypeScript peut formaliser ces contrats.

Une modification de la structure d’un objet peut immédiatement révéler plusieurs endroits devenus incompatibles.

L’autocomplétion et les refactorings deviennent également plus fiables lorsque l’éditeur connaît précisément les relations entre les composants.

L’intérêt augmente généralement avec la taille du projet et le nombre de développeurs qui y participent.

Développer une API Node.js

TypeScript peut être utilisé côté serveur avec Node.js et différents frameworks.

Les types permettent de décrire paramètres, objets métier, réponses de base de données et interfaces entre modules.

Ils peuvent également être partagés avec le front-end dans certains monorepos.

Cette cohérence ne remplace toutefois pas la validation à l’exécution : une requête HTTP extérieure peut contenir n’importe quelles données, même si le code TypeScript déclare qu’une propriété devrait être un nombre.

Des outils de validation restent donc nécessaires aux frontières du système.

Créer une bibliothèque JavaScript avec ses types

Un auteur de bibliothèque peut écrire son code en TypeScript puis publier à la fois le JavaScript généré et les déclarations .d.ts.

Les utilisateurs JavaScript continuent d’exécuter le package normalement.

Les utilisateurs TypeScript obtiennent en plus autocomplétion, documentation des paramètres et détection d’erreurs.

Cette capacité explique pourquoi un très grand nombre de bibliothèques npm publient aujourd’hui leurs types directement.

Refactorer une grande base de code

Sur plusieurs centaines ou milliers de fichiers, renommer une propriété ou modifier une signature peut devenir risqué avec une simple recherche textuelle.

TypeScript construit une représentation sémantique du projet.

L’éditeur peut alors identifier les véritables références à un symbole plutôt que toutes les chaînes de caractères qui lui ressemblent.

Le compilateur peut ensuite détecter les appels qui n’ont pas été adaptés.

Cette capacité à faire évoluer le code avec davantage de confiance constitue souvent un bénéfice plus important que les annotations elles-mêmes.

Conclusion

TypeScript est devenu l’un des outils les plus importants de l’écosystème JavaScript parce qu’il intervient précisément là où la flexibilité du langage d’origine peut devenir difficile à gérer : les grandes applications, les API complexes et les bases de code qui évoluent pendant plusieurs années.

Son principe reste relativement simple. Le développeur écrit du JavaScript enrichi avec des informations de type, le compilateur analyse ces informations puis produit du JavaScript utilisable par les environnements habituels.

La puissance réelle vient cependant de son système de types. Inférence, unions, narrowing, interfaces, generics, mapped types, conditional types et fichiers de déclaration permettent de décrire des API extrêmement riches sans ajouter nécessairement de logique au runtime.

Cette analyse améliore également considérablement les outils de développement. Navigation, refactoring et autocomplétion deviennent plus fiables lorsque l’éditeur comprend les relations sémantiques du programme.

TypeScript n’élimine pas tous les problèmes. Les types sont généralement effacés à la compilation et ne valident donc pas automatiquement les données reçues d’une API, d’un formulaire ou d’un fichier externe. Un programme peut également utiliser any, assertions ou configurations permissives qui contournent une partie de la sécurité.

Le système de types peut aussi devenir très complexe lorsque des bibliothèques construisent des combinaisons profondes de generics, conditional types et inférences avancées. Dans ce cas, la sophistication destinée à aider le développeur peut elle-même devenir difficile à maintenir.

TypeScript 7 apporte cependant un changement particulièrement important du côté de l’outillage. Le passage du compilateur vers une implémentation native en Go vise à réduire fortement les temps de compilation et d’analyse, avec des gains annoncés de l’ordre de 8x à 12x sur de nombreux builds complets.

Avec TypeScript 7.0.2 comme version stable actuelle, le projet conserve donc sa philosophie historique tout en reconstruisant son infrastructure pour mieux supporter les bases de code modernes de très grande taille.

Pour une équipe qui travaille déjà en JavaScript et cherche davantage de contrôle, de documentation implicite, de refactoring fiable et de détection d’erreurs sans abandonner l’écosystème Web, TypeScript reste aujourd’hui l’une des solutions les plus naturelles.

Points d’attention

  • TypeScript est construit au-dessus de JavaScript et produit généralement du JavaScript destiné au runtime final.

  • La version stable actuelle vérifiée est TypeScript 7.0.2, publiée le 20 août 2026.

  • TypeScript 7 utilise le nouveau compilateur natif écrit en Go, alors que les anciennes générations reposaient sur une implémentation TypeScript/JavaScript.

  • Microsoft annonce généralement des builds complets environ 8 à 12 fois plus rapides avec TypeScript 7, selon le projet et le matériel.

  • TypeScript est gratuit et open source sous licence Apache 2.0.

  • Les annotations de types sont généralement supprimées lors de la compilation. Elles ne constituent pas une validation automatique des données pendant l’exécution.

  • Une réponse API ou une entrée utilisateur doit toujours être validée au runtime lorsque sa provenance n’est pas fiable.

  • Le typage est principalement structurel, ce qui correspond bien à JavaScript mais diffère des systèmes nominaux de certains autres langages.

  • L’option strict est fortement recommandée pour les nouveaux projets, mais son activation sur une ancienne base de code peut révéler un grand nombre d’erreurs à corriger.

  • any contourne une grande partie du contrôle de types. unknown est souvent préférable lorsqu’une valeur est réellement inconnue.

  • TypeScript ne fournit pas automatiquement les polyfills nécessaires aux anciens environnements. Compiler vers une ancienne cible ne signifie pas que toutes les nouvelles API JavaScript deviennent disponibles.

  • Les fichiers .d.ts permettent de typer des bibliothèques JavaScript sans modifier leur code d’exécution.

  • DefinitelyTyped et les packages @types/* complètent les bibliothèques qui ne publient pas directement leurs propres déclarations de types.

  • TypeScript prend en charge JSX dans les fichiers .tsx, ce qui explique son adoption importante dans l’écosystème React.

  • Les réglages module et moduleResolution doivent correspondre au runtime ou au bundler réel. Une mauvaise combinaison peut créer des problèmes d’imports malgré une compilation apparemment correcte.

  • Le système de types avancé peut devenir très complexe. Les generics, mapped types et conditional types sont puissants mais ne doivent pas forcément être utilisés lorsque des types plus simples suffisent.

  • TypeScript ne remplace pas JavaScript : comprendre le comportement du langage JavaScript à l’exécution reste indispensable.