Menu

tsconfig.json expliqué : options, valeurs par défaut et exemples

tsconfig.json marque un dossier comme projet TypeScript et définit les options du compilateur. Les options qui comptent (target, module, moduleResolution, strict, rootDir, outDir, include, lib, types, noEmit, skipLibCheck), une configuration de départ recommandée, extends et ce qu'a changé TypeScript 7.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

tsconfig.json est le fichier de configuration d'un projet TypeScript. Quand vous lancez tsc sans argument, le compilateur le cherche dans le dossier courant (puis dans les dossiers parents), lit les options de compilerOptions et vérifie les fichiers listés par include. En voici un petit, mais complet :

{
    "compilerOptions": {
        "target": "es2022",
        "module": "nodenext",
        "strict": true,
        "rootDir": "./src",
        "outDir": "./dist"
    },
    "include": ["src"]
}

Cette configuration compile chaque fichier TypeScript de src en JavaScript dans dist, en code ES2022, avec les règles de modules de Node.js et toutes les vérifications strictes activées. npx tsc --init génère un fichier de départ plus long avec un commentaire sur chaque option.

Le fichier est du JSON avec commentaires : les commentaires //, les commentaires /* */ et les virgules finales sont tous acceptés.

Une configuration de départ recommandée

Pour une application ou un script Node.js :

{
    "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./dist",

        "target": "es2024",
        "lib": ["es2024"],
        "module": "nodenext",
        "types": ["node"],

        "strict": true,
        "noUncheckedIndexedAccess": true,
        "verbatimModuleSyntax": true,
        "skipLibCheck": true,
        "sourceMap": true
    },
    "include": ["src"]
}

Il faut npm install --save-dev @types/node pour les types de Node.js. Avec module: "nodenext", le champ "type" de package.json décide si un fichier .ts est un module ES ("type": "module") ou du CommonJS ("type": "commonjs", ce qu'écrit npm init -y). Utilisez "type": "module" pour les nouveaux projets qui utilisent import et export.

Pour du code construit par un bundler comme Vite, esbuild ou webpack, c'est le bundler qui écrit le JavaScript et tsc se contente de vérifier :

{
    "compilerOptions": {
        "target": "es2022",
        "lib": ["es2022", "dom"],
        "module": "preserve",
        "noEmit": true,

        "strict": true,
        "noUncheckedIndexedAccess": true,
        "verbatimModuleSyntax": true,
        "isolatedModules": true,
        "skipLibCheck": true,
        "jsx": "react-jsx"
    },
    "include": ["src"]
}

Les starters de frameworks (Vite, Next.js, Angular) génèrent leur propre tsconfig.json. Partez du leur plutôt que de le remplacer.

Les options qui comptent

OptionRôleValeur par défaut dans TypeScript 7
targetVersion JavaScript de la sortie ; la syntaxe récente est réécrite pour les cibles plus ancienneses2025
libTypes des API intégrées que connaît le vérificateur (Array.prototype.at, Map, document)Suit target, plus le DOM
moduleType de code de module émis et règles de modules appliquéesesnext
moduleResolutionComment les chemins d'import sont trouvés sur le disquenodenext ou node16 avec le module correspondant, sinon bundler
strictActive toute la famille des vérifications strictestrue
rootDirDossier dont la structure est reproduite dans outDirLe dossier qui contient tsconfig.json
outDirOù vont les fichiers .js (et .d.ts)À côté de chaque fichier source
include / exclude / filesQuels fichiers font partie du projetChaque fichier .ts sous le dossier
typesQuels paquets @types se chargent sans import[], aucun
noEmitVérifier seulement, ne rien écrirefalse
declarationÉcrire aussi des fichiers de déclaration de types .d.tsfalse
sourceMapÉcrire des fichiers .js.map pour les débogueursfalse
esModuleInteropPermet à import x from "cjs-package" de fonctionner avec les paquets CommonJStrue (impossible à désactiver)
skipLibCheckNe pas vérifier les types des fichiers .d.ts, y compris ceux de node_modulesfalse

target et lib

target indique sur quelle version de JavaScript la sortie doit tourner. La syntaxe plus récente que la cible est réécrite : avec "target": "es2017", un champ de classe ou ??= est transformé en code plus ancien. La cible la plus basse acceptée par TypeScript 7 est es2015 (es6) ; es5 a été supprimé.

target n'ajoute pas les API d'exécution manquantes. Les décrire est le rôle de lib, les fournir celui d'un polyfill. lib indique au vérificateur quels objets et méthodes intégrés existent. Sa valeur par défaut suit target et inclut aussi les types du DOM du navigateur, si bien que document passe la vérification même dans un projet Node.js tant que vous ne réglez pas lib vous-même. Utiliser une méthode d'un standard plus récent que votre lib est une erreur de compilation :

src/b.ts(1,24): error TS2550: Property 'toSorted' does not exist on type 'number[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2023' or later.

Les exemples exécutables de cette documentation utilisent le lib es2022 : toSorted, Object.groupBy et les nouvelles méthodes de Set n'y sont donc pas disponibles.

module et moduleResolution

module a trois valeurs raisonnables pour du nouveau code :

  • nodenext : pour le code exécuté par Node.js. Chaque fichier est ESM ou CommonJS selon son extension (.mts, .cts) ou le "type" du package.json le plus proche, exactement comme Node le décide. Les imports relatifs dans les modules ES demandent une extension de fichier, écrite .js même si la source est en .ts : import { add } from "./math.js". moduleResolution suit automatiquement.
  • preserve : pour le code traité par un bundler. Les imports sont laissés tels quels, et la résolution utilise les règles bundler, qui autorisent les imports sans extension.
  • esnext : une sortie en modules ES simple, avec la résolution bundler. C'est la valeur par défaut quand module n'est pas réglé.

Une première erreur fréquente avec la configuration de tsc --init vient de npm init -y, qui écrit "type": "commonjs" :

src/main.ts(1,10): error TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.

Le fichier utilise import, mais package.json indique que le projet est en CommonJS. Passez "type" à "module". La page sur les modules traite en détail des imports et des exports.

strict et les options de vérification

"strict": true active d'un coup un groupe de vérifications : noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, strictBuiltinIteratorReturn, noImplicitThis et useUnknownInCatchVariables. C'est la valeur par défaut dans TypeScript 7, et elle est activée dans tous les exemples exécutables ici. Du code écrit pour le mode strict affine le type avant d'utiliser une valeur qui peut manquer :

Sans annotation, le type d'un paramètre ne peut pas être inféré, et noImplicitAny le signale :

index.ts(2,17): error TS7006: Parameter 'n' implicitly has an 'any' type.

strict n'inclut pas toutes les vérifications utiles. Deux méritent d'être ajoutées : noUncheckedIndexedAccess (un élément de tableau ou une lecture via une signature d'index est de type T | undefined) et exactOptionalPropertyTypes (une propriété optionnelle ne peut pas recevoir explicitement undefined) ; tsc --init active les deux. Les vérifications de style comme noUnusedLocals, noImplicitReturns et noFallthroughCasesInSwitch sont désactivées par défaut.

Quels fichiers : include, exclude, rootDir, outDir

Sans include ni files, le projet contient chaque fichier .ts, .tsx et .d.ts du dossier et de ses sous-dossiers. node_modules est toujours exclu. outDir est exclu aussi, mais seulement tant que vous n'avez pas réglé exclude : une liste exclude personnalisée remplace ce comportement par défaut, ajoutez-y donc le dossier de sortie. include et exclude acceptent des motifs glob :

{
    "include": ["src", "scripts/**/*.ts"],
    "exclude": ["src/**/*.test.ts"]
}

exclude ne fait que filtrer ce que include a trouvé. Un fichier importé par un autre fichier inclus est quand même compilé.

outDir est l'endroit où va la sortie, et rootDir la partie de l'arborescence source qui y est reproduite : avec "rootDir": "./src", src/api/users.ts devient dist/api/users.js. Réglez les deux. rootDir vaut par défaut le dossier qui contient tsconfig.json : si vous ne réglez que outDir alors que les sources sont dans src, TypeScript 7 s'arrête avec :

error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.

Options de sortie : noEmit, declaration, sourceMap

  • "noEmit": true fait de tsc un pur vérificateur de types. Utilisez-le quand un autre outil (un bundler, tsx, le type stripping de Node.js) produit le JavaScript.
  • "declaration": true écrit un fichier .d.ts par module, c'est-à-dire les types sans le code. Les bibliothèques en ont besoin pour que leurs utilisateurs aient les types. declarationMap ajoute des maps pour que « aller à la définition » mène à la source .ts.
  • "sourceMap": true écrit des fichiers .js.map pour que les débogueurs et les stack traces pointent vers les lignes du .ts.
  • "noEmitOnError": true n'écrit rien tant qu'il reste des erreurs de type. Sans cette option, tsc signale les erreurs et écrit quand même le JavaScript.

types, esModuleInterop et skipLibCheck

types liste les paquets @types chargés globalement, sans import. La valeur par défaut de TypeScript 7 est une liste vide : après npm install --save-dev @types/node, ajoutez donc aussi "types": ["node"], sinon process et require restent inconnus (error TS2591: Cannot find name 'process'). Les lanceurs de tests qui ont des fonctions globales, comme le describe de Jest, vont dans la même liste.

esModuleInterop fait fonctionner les imports par défaut de paquets CommonJS (import express from "express"). Il est toujours actif dans TypeScript 7, et le régler à false est une erreur.

skipLibCheck saute la vérification des types des fichiers de déclaration. Il accélère les builds et évite les erreurs dans node_modules que vous ne pouvez pas corriger, au prix de ne pas remarquer les conflits entre les types de deux bibliothèques. La plupart des projets l'activent.

Partager des réglages avec extends

extends charge une autre configuration et permet à ce fichier d'en surcharger certaines parties :

{
    "extends": "./tsconfig.base.json",
    "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./dist"
    },
    "include": ["src"]
}

Les compilerOptions sont fusionnées option par option, tandis que include, exclude et files de la base sont remplacés, et non fusionnés, si ce fichier les définit. Les chemins du fichier de base sont résolus par rapport au fichier de base. extends accepte aussi un paquet : le projet @tsconfig/bases en publie un par environnement, par exemple npm install --save-dev @tsconfig/node24 puis "extends": "@tsconfig/node24/tsconfig.json".

Pour voir les réglages finaux une fois tous les extends et les valeurs par défaut appliqués, lancez :

npx tsc --showConfig

Options supprimées dans TypeScript 7

TypeScript 6 a déprécié ces réglages et TypeScript 7 les a supprimés. Une configuration qui en utilise encore un échoue avec error TS5108 ou TS5102, par exemple Option 'baseUrl' has been removed. Please remove it from your configuration.

Réglage suppriméÀ utiliser à la place
"target": "es5"es2015 ou plus récent
"moduleResolution": "node" (node10) ou "classic"nodenext ou bundler
"module": "amd", "umd", "system", "none"nodenext, esnext ou preserve, et un bundler pour les autres formats
baseUrlDes entrées paths relatives au fichier tsconfig
outFileUn bundler
downlevelIterationRien : les cibles à partir de es2015 gèrent l'itération nativement
"esModuleInterop": false, "allowSyntheticDefaultImports": false, "alwaysStrict": falseSupprimez la ligne ; ces options sont toujours actives

La page TypeScript 7 liste les autres changements de cette version, y compris les nouvelles valeurs par défaut que ce tableau ne couvre pas.

Questions fréquentes

Qu'est-ce que tsconfig.json ?

C'est le fichier de configuration d'un projet TypeScript. Sa présence marque le dossier comme racine du projet, compilerOptions règle la façon dont le compilateur vérifie et émet le code, et include, exclude ou files indiquent quels fichiers appartiennent au projet. Lancer tsc sans argument lit ce fichier.

Comment créer un fichier tsconfig.json ?

Lancez npx tsc --init dans le dossier du projet (avec TypeScript installé). La commande écrit un tsconfig.json avec des réglages recommandés et un commentaire sur chaque option. Vous pouvez aussi écrire le fichier à la main ; {} est un tsconfig valide qui utilise toutes les valeurs par défaut.

Quelle valeur donner à target dans tsconfig ?

La plus ancienne version de JavaScript sur laquelle votre code doit tourner. Pour un Node.js actuel, es2022 ou plus récent ne pose aucun problème ; la valeur par défaut de TypeScript 7 est es2025. target détermine quelle syntaxe récente est réécrite pour les moteurs plus anciens et choisit aussi le lib par défaut, l'ensemble des API intégrées que connaît le vérificateur.

Quelle est la différence entre module et moduleResolution ?

module décide du type de code de module écrit par le compilateur (import/export ES ou require CommonJS) et des règles de modules appliquées. moduleResolution décide comment un chemin d'import comme "./utils.js" ou "lodash" est trouvé sur le disque. Utilisez nodenext pour le code exécuté par Node.js, et module: "preserve" (qui implique la résolution bundler) pour le code traité par un bundler.

Peut-on mettre des commentaires dans tsconfig.json ?

Oui. Le compilateur le lit comme du JSON avec commentaires : les commentaires // et /* */ et les virgules finales sont acceptés, c'est pourquoi tsc --init écrit un fichier plein d'options commentées. D'autres outils qui le lisent comme du JSON strict peuvent échouer dessus.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER