Cours JavaScript et TypeScript · Module 6: Bases de TypeScript
Le compilateur TypeScript (tsc)
Dans cette leçon13
Introduction : le laboratoire InGen
Bienvenue au laboratoire génétique InGen ! Tout comme les scientifiques du parc transforment d'anciennes séquences d'ADN en dinosaures vivants, le compilateur TypeScript transforme le code TypeScript en JavaScript standard qui peut s'exécuter dans un navigateur ou un environnement Node.js.
Le Dr Wu, le généticien en chef du parc, dit souvent : « Nous donnons vie à du code vieux de plusieurs millions d'années. » De même, le compilateur TypeScript nous permet d'écrire du code dans un langage moderne qui est ensuite transformé en une forme plus « primitive » de JavaScript, compréhensible par tous les environnements.
Qu'est-ce que le compilateur TypeScript ?
Le compilateur TypeScript (généralement appelé tsc - TypeScript Compiler) est un outil qui analyse ton code TypeScript, vérifie les types, puis génère le code JavaScript correspondant. C'est un pont entre le monde du TypeScript typé statiquement et celui du JavaScript typé dynamiquement.
Dans la terminologie du Jurassic Park, on peut dire que :
- Le code TypeScript est comme les séquences d'ADN isolées d'un dinosaure
- Le processus de compilation est comme la procédure de clonage
- Le code JavaScript généré est le dinosaure vivant, prêt à être relâché dans le parc
Bases de l'utilisation du compilateur tsc
Installer le compilateur
Avant de commencer les expériences génétiques, nous avons besoin du bon équipement :
1# Installation globale (donne accès à la commande tsc sur tout le système)
2npm install -g typescript
3
4# Installation locale (uniquement à l'intérieur du projet)
5npm install --save-dev typescriptCompiler un seul fichier
Compiler un seul fichier TypeScript, c'est comme créer un seul dinosaure au laboratoire :
1# Syntaxe : tsc [nomdufichier].ts
2tsc security-system.tsAprès avoir exécuté cette commande, un fichier JavaScript du même nom sera créé : security-system.js.
Compiler un projet entier
Dans un vrai Jurassic Park, nous ne créons pas des dinosaures individuels : nous construisons tout un écosystème. De même, dans les projets plus importants, nous compilons plusieurs fichiers à la fois :
1# Compiler tout le projet selon tsconfig.json
2tsc
3
4# Compiler en mode watch - le compilateur surveille les changements et recompile automatiquement
5tsc --watchLe processus de compilation
Le processus de compilation TypeScript se déroule en plusieurs étapes, semblables au processus de création d'un dinosaure au laboratoire :
- Scan - le compilateur analyse tous les fichiers source et leurs dépendances
- Analyse syntaxique (parsing) - transforme le code source en un arbre syntaxique abstrait (AST)
- Vérification des types - vérifie que les types sont cohérents et émet des avertissements/erreurs
- Transformations - transforme l'AST en structures JavaScript appropriées
- Émission - génère les fichiers JavaScript, les source maps et les fichiers de déclaration de types
Ce processus peut être comparé aux étapes de la création d'un dinosaure :
- Le scan, c'est la collecte d'échantillons d'ADN provenant de différentes sources
- L'analyse syntaxique, c'est le séquençage de l'ADN
- La vérification des types, c'est s'assurer que les séquences sont correctes et compatibles
- Les transformations, ce sont les modifications génétiques pour que l'ADN fonctionne dans un environnement moderne
- L'émission, c'est placer le code génétique fini dans un œuf de dinosaure
Les options de ligne de commande les plus importantes
Le compilateur TypeScript offre de nombreuses options de ligne de commande qui permettent de contrôler précisément le processus de compilation :
Options pour les types de fichiers de sortie
1# Spécifier le répertoire de sortie
2tsc --outDir ./dist
3
4# Générer les fichiers de déclaration de types (.d.ts)
5tsc --declaration
6
7# Générer les source maps (.js.map) pour faciliter le débogage
8tsc --sourceMap
9
10# Fusionner plusieurs fichiers de sortie en un seul (déconseillé pour les modules ES)
11tsc --outFile ./dist/bundle.jsOptions contrôlant le processus de compilation
1# Compiler sans émettre de fichiers (vérification des types uniquement)
2tsc --noEmit
3
4# Compiler malgré les erreurs
5tsc --noEmitOnError false
6
7# Activer le mode strict
8tsc --strict
9
10# Compiler en mode watch (recompilation automatique lors des changements)
11tsc --watchOptions affectant le code généré
1# Spécifier la version JavaScript cible (ES5, ES6, etc.)
2tsc --target ES2015
3
4# Spécifier le système de modules (commonjs, amd, system, esm, etc.)
5tsc --module commonjs
6
7# Préserver la structure des répertoires
8tsc --rootDir ./srcOptions de diagnostic
1# Afficher des informations détaillées sur le processus de compilation
2tsc --verbose
3
4# Lister tous les fichiers qui font partie de la compilation
5tsc --listFiles
6
7# Afficher la configuration résultante
8tsc --showConfigComment TypeScript compile-t-il les différentes constructions de code ?
Voyons comment le compilateur transforme des constructions TypeScript spécifiques en JavaScript :
1. Les interfaces et les types - disparaissent lors de la compilation
1// TypeScript code (security-types.ts)
2interface Employee {
3 id: number;
4 name: string;
5 role: string;
6 accessLevel: number;
7}
8
9type AccessLevel = 1 | 2 | 3 | 4 | 5;
10
11function checkAccess(employee: Employee, requiredLevel: AccessLevel): boolean {
12 return employee.accessLevel >= requiredLevel;
13}1// Compiled JavaScript (security-types.js)
2function checkAccess(employee, requiredLevel) {
3 return employee.accessLevel >= requiredLevel;
4}Les interfaces et les types ne servent que lors de la vérification des types et sont complètement supprimés du code JavaScript. C'est comme l'ADN d'un dinosaure : important lors de la création, mais invisible dans la créature finale.
2. Les annotations de type - également supprimées
1// TypeScript code (employee.ts)
2function createEmployee(name: string, role: string, accessLevel: number): Employee {
3 return {
4 id: generateId(),
5 name,
6 role,
7 accessLevel
8 };
9}
10
11let newEmployee: Employee;1// Compiled JavaScript (employee.js)
2function createEmployee(name, role, accessLevel) {
3 return {
4 id: generateId(),
5 name,
6 role,
7 accessLevel
8 };
9}
10
11let newEmployee;Les annotations de type disparaissent, mais la structure du code reste la même. C'est comme une carte génétique utilisée pour créer un dinosaure, mais qui n'est pas transférée à la créature finale.
3. Les fonctionnalités avancées de TypeScript qui nécessitent une transformation
1// TypeScript code (tracking-system.ts)
2// Using optional chaining and nullish coalescing operator
3function getLocationName(dinosaur?: Dinosaur) {
4 return dinosaur?.currentLocation?.name ?? "Unknown Location";
5}
6
7// Using rest parameters and destructuring
8function analyzeDinosaurs(...dinosaurs: Dinosaur[]) {
9 const [mostDangerous, ...others] = dinosaurs.sort((a, b) => b.dangerLevel - a.dangerLevel);
10 return { mostDangerous, others };
11}La compilation peut être différente selon la version ES cible. Pour ES5, elle pourrait ressembler à ceci :
1// Compiled JavaScript (tracking-system.js) for ES5
2function getLocationName(dinosaur) {
3 var _a, _b;
4 return (_b = (_a = dinosaur === null || dinosaur === void 0 ? void 0 : dinosaur.currentLocation) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "Unknown Location";
5}
6
7function analyzeDinosaurs() {
8 var dinosaurs = [];
9 for (var _i = 0; _i < arguments.length; _i++) {
10 dinosaurs[_i] = arguments[_i];
11 }
12 var sortedDinosaurs = dinosaurs.sort(function (a, b) { return b.dangerLevel - a.dangerLevel; });
13 var mostDangerous = sortedDinosaurs[0], others = sortedDinosaurs.slice(1);
14 return { mostDangerous: mostDangerous, others: others };
15}Ici, le compilateur a dû fournir beaucoup plus de travail pour transformer les fonctionnalités JavaScript modernes en code compatible ES5. C'est comme adapter un code génétique « primitif » pour qu'il fonctionne dans un environnement moderne.
4. Les classes TypeScript
1// TypeScript code (dinosaur.ts)
2class Dinosaur {
3 private _healthStatus: number = 100;
4
5 constructor(
6 public readonly species: string,
7 public age: number,
8 private readonly dangerLevel: number
9 ) {}
10
11 get health(): number {
12 return this._healthStatus;
13 }
14
15 feed(amount: number): void {
16 this._healthStatus = Math.min(100, this._healthStatus + amount);
17 console.log(`${this.species} has been fed. New health: ${this._healthStatus}%`);
18 }
19}1// Compiled JavaScript (dinosaur.js) for ES2015
2class Dinosaur {
3 constructor(species, age, dangerLevel) {
4 this.species = species;
5 this.age = age;
6 this.dangerLevel = dangerLevel;
7 this._healthStatus = 100;
8 }
9
10 get health() {
11 return this._healthStatus;
12 }
13
14 feed(amount) {
15 this._healthStatus = Math.min(100, this._healthStatus + amount);
16 console.log(`${this.species} has been fed. New health: ${this._healthStatus}%`);
17 }
18}Pour ES5, les classes seront transformées en fonctions constructeurs et en prototypes.
Les fichiers de déclaration de types (.d.ts)
Au laboratoire InGen, une documentation détaillée est tenue pour toutes les espèces créées. Dans le monde de TypeScript, l'équivalent d'une telle documentation, ce sont les fichiers de déclaration de types (.d.ts).
Ces fichiers ne contiennent que des informations de type, sans implémentation. Ils sont utilisés par les IDE et le compilateur pour fournir des suggestions de code et la vérification des types.
1// dinosaur.d.ts - type declaration file for the Dinosaur class
2declare class Dinosaur {
3 readonly species: string;
4 age: number;
5 private readonly dangerLevel: number;
6 private _healthStatus: number;
7
8 constructor(species: string, age: number, dangerLevel: number);
9
10 get health(): number;
11 feed(amount: number): void;
12}Pour générer les fichiers de déclaration de types de ton projet, tu peux utiliser l'option --declaration :
1tsc --declarationLes source maps
Déboguer des dinosaures peut être compliqué : nous ne savons pas toujours quelle séquence d'ADN correspond à un comportement donné. De même, déboguer du code JavaScript compilé peut être difficile sans source maps.
Les source maps sont des fichiers .js.map` qui permettent au navigateur ou à l'environnement Node.js de faire correspondre le code JavaScript compilé au code TypeScript d'origine. Cela te permet de déboguer directement le code TypeScript, même lorsque c'est le JavaScript qui s'exécute.
Pour générer les source maps, utilise l'option --sourceMap :
1tsc --sourceMapLes projets (tsconfig.json)
Dans un grand parc rempli de différentes espèces de dinosaures, nous avons besoin de plans et de spécifications détaillés. De même, dans les projets TypeScript plus importants, nous utilisons le fichier tsconfig.json pour configurer le compilateur.
Ce fichier te permet de définir toutes les options du compilateur en un seul endroit, ce qui est bien plus pratique que de les passer à chaque fois en ligne de commande.
1# Créer un fichier tsconfig.json de base
2tsc --init
3
4# Compiler le projet selon la configuration
5tscSupprimer les erreurs et migration progressive
Le Dr Wu doit parfois ignorer certaines incompatibilités génétiques pour qu'un dinosaure puisse survivre. De même, lors de la migration d'un projet JavaScript existant vers TypeScript, nous pouvons avoir besoin d'ignorer temporairement certaines erreurs de type.
Ignorer les erreurs sur des lignes spécifiques
1// @ts-ignore
2element.style.background = 'red'; // TypeScript signalerait une erreur, mais nous l'ignorons
3
4// @ts-expect-error
5console.log(dinosaur.location); // Nous documentons que nous attendons une erreur iciUtilisation temporaire du type any
1function legacyFunction(data: any) {
2 // Nous utilisons temporairement 'any', mais prévoyons de corriger cela plus tard
3 return data.process();
4}Activer progressivement la vérification des types
Nous pouvons aussi activer progressivement la vérification des types dans tout le projet, en commençant par des réglages moins stricts :
1// tsconfig.json avec des réglages moins stricts
2{
3 "compilerOptions": {
4 "allowJs": true, // Autorise la compilation des fichiers .js
5 "checkJs": false, // Ne vérifie pas les types dans les fichiers .js
6 "noImplicitAny": false, // Autorise le type 'any' implicite
7 "strictNullChecks": false // N'exige pas de vérifier null/undefined
8 }
9}Avec le temps, à mesure que le projet est davantage « apprivoisé », nous pouvons augmenter progressivement la rigueur de la vérification des types.
Problèmes courants du compilateur et leurs solutions
1. Conflit de versions de TypeScript
Problème : une installation globale de TypeScript peut entrer en conflit avec la version locale du projet.
Solution : utilise le compilateur installé localement via npx :
1npx tsc2. Chemins incorrects
Problème : le compilateur ne trouve pas les fichiers ou compile les mauvais fichiers.
Solution : vérifie les réglages include, exclude, rootDir et outDir dans tsconfig.json :
1{
2 "compilerOptions": {
3 "rootDir": "./src",
4 "outDir": "./dist"
5 },
6 "include": ["src/**/*"],
7 "exclude": ["node_modules", "**/*.spec.ts"]
8}3. Incompatibilités de types avec des bibliothèques
Problème : TypeScript signale des erreurs concernant les types dans des bibliothèques externes.
Solution : installe les fichiers de définition de types appropriés ou crée les tiens :
1npm install --save-dev @types/libraryOu crée ton propre fichier de définition :
1// types/missing-library.d.ts
2declare module 'missing-library' {
3 export function someFunction(): void;
4}4. Erreurs dans des types génériques complexes
Problème : TypeScript a du mal avec les types inférés dans des structures génériques complexes.
Solution : fournis des annotations de type explicites à des endroits stratégiques :
1// Au lieu de laisser TypeScript inférer le type :
2const result = complexFunction(data);
3
4// Fournis une annotation de type explicite :
5const result: ExpectedReturnType = complexFunction(data);Utilisation avancée : l'API du compilateur
Pour les scénarios les plus avancés, TypeScript fournit une API de compilation qui permet une intégration profonde avec les outils de développement. C'est comme avoir accès à des outils de laboratoire avancés pour des expériences génétiques particulièrement exigeantes.
1import * as ts from 'typescript';
2
3// On crée un compiler host
4const host = ts.createCompilerHost({});
5
6// On crée un programme TypeScript
7const program = ts.createProgram(['file1.ts', 'file2.ts'], {
8 target: ts.ScriptTarget.ES2015,
9 module: ts.ModuleKind.CommonJS
10}, host);
11
12// On compile le programme
13const emitResult = program.emit();
14
15// On récupère les diagnostics (erreurs et avertissements)
16const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
17
18// On affiche les diagnostics
19diagnostics.forEach(diagnostic => {
20 if (diagnostic.file) {
21 const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
22 const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
23 console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
24 } else {
25 console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
26 }
27});Cette fonctionnalité est utilisée par des outils comme webpack, Rollup ou ESBuild pour intégrer la compilation TypeScript dans leurs propres processus de build.
Résumé
Le compilateur TypeScript, comme le laboratoire génétique InGen, transforme un code avancé et sûr (TypeScript) en une forme qui peut être « ramenée à la vie » dans un navigateur ou un environnement Node.js (JavaScript).
Points clés :
Le compilateur TypeScript (
tsc) transforme le code TypeScript en JavaScript, en supprimant les annotations de type et en transformant les fonctionnalités avancées.Le processus de compilation comprend : le scan, l'analyse syntaxique, la vérification des types, les transformations et l'émission.
Il existe de nombreuses options de compilation qui peuvent être passées en ligne de commande ou configurées dans
tsconfig.json.Chaque fonctionnalité de TypeScript a une façon de se compiler en JavaScript, la complexité de cette compilation dépendant de la version JavaScript cible.
Les fichiers
.d.tset les source maps.js.mapaident à la documentation et au débogage.Lors de la migration de projets existants, TypeScript permet d'introduire les types progressivement.
Pour les scénarios avancés, il existe une API de compilation TypeScript.
Tout comme le laboratoire InGen a besoin de protocoles et d'outils précis pour créer des dinosaures, les programmeurs ont besoin d'un compilateur TypeScript bien configuré pour créer des applications JavaScript sûres et efficaces.
Dans la prochaine leçon, nous plongerons dans les types de base disponibles en TypeScript : ce sera comme étudier différentes espèces de dinosaures dans notre parc !
Code de cette leçon : index.ts
1// TypeScript Compiler - Laboratoire InGen
2console.log("Compilateur TypeScript en action !\n");
3
4// ===========================================
5// 1. Bases de la compilation
6// ===========================================
7console.log("=== BASES DE LA COMPILATION ===");
8console.log("TypeScript -> tsc -> JavaScript\n");
9
10// This kod TypeScript will be compilé en JavaScript
11interface Dinosaur {
12 species: string;
13 period: 'Triassic' | 'Jurassic' | 'Cretaceous';
14 diet: 'carnivore' | 'herbivore' | 'omnivore';
15 weight: number;
16}
17
18const trex: Dinosaur = {
19 species: "Tyrannosaurus Rex",
20 period: 'Cretaceous',
21 diet: 'carnivore',
22 weight: 8000
23};
24
25console.log("Dinosaur data:", trex);
26
27// ===========================================
28// 2. Compilation with type checking
29// ===========================================
30console.log("\n=== TYPE CHECKING ===");
31
32function calculateFeedAmount(dino: Dinosaur): number {
33 // Predators eat 5% of their weight daily
34 // Herbivores eat 10% of their weight daily
35 const percentage = dino.diet === 'carnivore' ? 0.05 : 0.10;
36 return dino.weight * percentage;
37}
38
39const feedAmount = calculateFeedAmount(trex);
40console.log(`Daily feed for ${trex.species}: ${feedAmount}kg`);
41
42// ===========================================
43// 3. Target ES version
44// ===========================================
45console.log("\n=== TARGET ES VERSION ===");
46
47// Arrow functions (ES6+)
48const getDinosaurs = (): Dinosaur[] => [trex];
49
50// Template literals (ES6+)
51const description = `${trex.species} lived in ${trex.period} period`;
52console.log(description);
53
54// Optional chaining (ES2020+)
55interface Park {
56 dinosaurs?: Dinosaur[];
57}
58
59const park: Park = { dinosaurs: getDinosaurs() };
60const firstDino = park.dinosaurs?.[0];
61console.log("First dinosaur:", firstDino?.species);
62
63// ===========================================
64// 4. Modules
65// ===========================================
66console.log("\n=== MODULES ===");
67
68// Export/Import (ES6 modules)
69export class DinosaurManager {
70 private dinosaurs: Dinosaur[] = [];
71
72 add(dino: Dinosaur): void {
73 this.dinosaurs.push(dino);
74 console.log(`Added ${dino.species} to collection`);
75 }
76
77 getAll(): Dinosaur[] {
78 return [...this.dinosaurs];
79 }
80
81 findByDiet(diet: Dinosaur['diet']): Dinosaur[] {
82 return this.dinosaurs.filter(d => d.diet === diet);
83 }
84}
85
86const manager = new DinosaurManager();
87manager.add(trex);
88console.log("Total dinosaurs:", manager.getAll().length);
89
90// ===========================================
91// 5. File generation
92// ===========================================
93console.log("\n=== FICHIERS GÉNÉRÉS ===");
94console.log("JavaScript (.js) - code exécutable");
95console.log("Source Maps (.js.map) - mapping vers TS");
96console.log("Declaration Files (.d.ts) - type definitions");
97
98console.log("\nCompilateur TypeScript prêt à travailler !");Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle commande exécute le compilateur TypeScript ?
2. Que fait l’option 'strict: true' dans tsconfig.json ?
Tâches pratiques dans le jeu
- Éditeur de code
Définis une fonction avec des types de paramètres et vérifie les erreurs de compilation.
- Clique dans l'ordre
Ordonne la commande de compilation TypeScript avec le répertoire de sortie :
- Tri vertical
Ordonne les étapes du processus de compilation TypeScript :