Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Angular

Les types de variables en TypeScript

En TypeScript, chaque variable possède un type, fixé à sa déclaration par une annotation ou deviné par inférence. Ce chapitre explique comment let et const influencent ce type, puis détaille les types...

0 chapitres 0 QCM Accès gratuit
Dans cet article

À propos de ce cours

En TypeScript, chaque variable possède un type, fixé à sa déclaration par une annotation ou deviné par inférence. Ce chapitre explique comment let et const influencent ce type, puis détaille les types primitifs (string, number, boolean, bigint), les tableaux et les tuples. Vous apprendrez à combiner des types avec les unions et les types littéraux, à rétrécir un type avec typeof, et à figer une valeur avec as const. Vous verrez aussi comment gérer les valeurs absentes avec ?. et ??, et pourquoi préférer unknown à any et satisfies à as. Cinq activités et un exemple de composant Angular avec des signals typés complètent le chapitre.
  1. Objectifs

    • Savoir ce qu'est TypeScript et pourquoi Angular l'utilise
    • Comprendre la relation entre TypeScript et JavaScript (surensemble)
    • Repérer les erreurs avant l'exécution grâce au typage statique
    • Installer TypeScript et compiler un fichier avec tsc
    • Écrire des annotations de type et profiter de l'inférence
    • Connaître les types de base, typer une fonction et un objet
    • Configurer un projet avec tsconfig.json, compiler en mode --watch
    • Lire et corriger les messages d'erreur du compilateur
  2. Présentation

    • TypeScript est un langage libre et open source créé par Microsoft en 2012, sous la direction d'Anders Hejlsberg (également créateur de C#).
    • C'est du JavaScript avec des types: on indique la nature des données (chaîne, nombre, objet…) et un outil, le compilateur tsc, vérifie que le code les respecte, puis le transforme en JavaScript ordinaire.
    • Le navigateur et Node.js n'exécutent que du JavaScript : le code TypeScript est donc toujours compilé (on dit aussi transpilé) avant d'être exécuté.
    • TypeScript apporte :
      • la détection des erreurs pendant l'écriture du code, et non plus chez l'utilisateur ;
      • une autocomplétion précise dans l'éditeur (VS Code est lui-même écrit en TypeScript) ;
      • un code plus lisible et plus facile à maintenir à plusieurs : le type d'un paramètre documente la fonction.
    • Angular est écrit en TypeScript et l'impose depuis Angular 2 : composants, services, routes, formulaires… tout le code d'un projet Angular est en TypeScript.
    • Repère de versions : TypeScript 7.0 (été 2026) a un compilateur entièrement réécrit en Go, environ dix fois plus rapide ; le langage, lui, ne change pas. TypeScript 6.0 (mars 2026) a été la dernière version dont le compilateur est écrit en JavaScript.
  3. TypeScript, un surensemble de JavaScript

    • TypeScript est un surensemble (superset) de JavaScript : il contient tout JavaScript (let, const, fonctions fléchées, déstructuration, classes, modules…) et ajoute par-dessus un système de types.
    • Conséquence pratique : tout ce que vous avez appris dans les chapitres précédents reste valable. On ne change pas de langage, on l'enrichit.

TypeScript, un surensemble de JavaScript

  • Un fichier JavaScript renommé en .ts reste valide. On ajoute ensuite les types petit à petit, en écrivant : type après un nom :
// JavaScript (fichier .js)
const tva = 0.19;
const prixTTC = (ht) => ht * (1 + tva);

// TypeScript (fichier .ts) : le même code, avec des types
const tva2: number = 0.19;
const prixTTC2 = (ht: number): number => ht * (1 + tva2);

console.log(prixTTC2(45).toFixed(3));   // 53.550
  • Remarque : l'inverse n'est pas vrai. Un fichier contenant : number n'est pas du JavaScript valide : un navigateur qui le lirait directement afficherait une SyntaxError. D'où la compilation.
  • Pourquoi typer son code ?

    • JavaScript est un langage à typage dynamique: le type d'une variable n'est connu qu'au moment de l'exécution. Une faute de frappe ou un mauvais argument passe inaperçu… jusqu'à ce que la ligne s'exécute.
    // panier.js
    function calculerTotal(prix, quantite) {
      return prix * quantite;
    }
    
    console.log(calculerTotal(45, 2));     // 90
    console.log(calculerTotal('45', 2));   // 90 : conversion implicite, ça marche… par chance
    console.log(calculerTotal(45));        // NaN : argument oublié, aucune alerte
    
    const stagiaire = { nom: 'Ben Ali', prenom: 'Amira' };
    console.log(stagiaire.prnom.toUpperCase());
    // TypeError: Cannot read properties of undefined (reading 'toUpperCase')
    • TypeScript a un typage statique: les types sont vérifiés avant l'exécution, par le compilateur et par l'éditeur. Le même code, typé, est refusé immédiatement, avec le fichier, la ligne, la colonne et un code d'erreur TSxxxx:
    // panier.ts
    function calculerTotal(prix: number, quantite: number): number {
      return prix * quantite;
    }
    
    console.log(calculerTotal(45, 2));
    console.log(calculerTotal('45', 2));
    // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
    console.log(calculerTotal(45));
    // error TS2554: Expected 2 arguments, but got 1.
    
    const stagiaire = { nom: 'Ben Ali', prenom: 'Amira' };
    console.log(stagiaire.prnom.toUpperCase());
    // error TS2551: Property 'prnom' does not exist on type '{ nom: string; prenom: string; }'. Did you mean 'prenom'?

    Erreur découverte à l'exécution en JavaScript, à la compilation en TypeScript

    • Remarquez que TypeScript n'a pas eu besoin qu'on écrive le type de stagiaire: il l'a deviné à partir de sa valeur. C'est l'inférence de type, détaillée plus loin.
  • Installer TypeScript

    • TypeScript s'installe avec npm, livré avec Node.js. Vérifier d'abord que Node.js est installé (version 22.18 ou plus récente conseillée).
    • On l'installe dans le projet, comme dépendance de développement : chaque projet garde ainsi sa propre version du compilateur.
    node --version                    # v22.18.0 ou plus récent
    
    mkdir premiers-pas-typescript
    cd premiers-pas-typescript
    npm init -y                       # crée package.json
    npm install --save-dev typescript # installe le compilateur dans node_modules
    
    npx tsc --version                 # Version 7.0.2
    • npx exécute la commande tsc installée dans le projet (node_modules/.bin).
    • Une installation globale (npm install -g typescript) permet d'écrire tsc directement, partout. Elle est pratique pour tester, mais on préfère l'installation locale dans un vrai projet.
    • Remarque : dans un projet Angular, vous n'installez rien : ng new installe automatiquement la version de TypeScript compatible avec votre version d'Angular.
  • Premier programme : compiler avec tsc

    • Créer le fichier bonjour.ts:
    const prenom: string = 'Amira';
    const age: number = 22;
    
    function saluer(nom: string, annees: number): string {
      return `Bonjour ${nom}, vous avez ${annees} ans.`;
    }
    
    console.log(saluer(prenom, age));
    • Le compiler, puis exécuter le fichier JavaScript produit :
    npx tsc bonjour.ts      # crée bonjour.js à côté de bonjour.ts
    node bonjour.js         # Bonjour Amira, vous avez 22 ans.
    • Ouvrir bonjour.js: c'est le même code, sans les types. Ils ont servi à la vérification, puis ont été effacés.
    "use strict";
    const prenom = 'Amira';
    const age = 22;
    function saluer(nom, annees) {
        return `Bonjour ${nom}, vous avez ${annees} ans.`;
    }
    console.log(saluer(prenom, age));

    La compilation d'un fichier TypeScript avec tsc

    • Si l'on remplace saluer(prenom, age) par saluer(prenom, '22'), tsc affiche l'erreur dans le terminal :
    bonjour.ts:8:28 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
    
    8 console.log(saluer(prenom, '22'));
                                 ~~~~
    
    Found 1 error in bonjour.ts:8
    • Lire un message d'erreur : fichier:ligne:colonne, puis le code de l'erreur (TS2345), puis l'explication. Le code permet de chercher l'erreur sur Internet.
    • Attention : par défaut, tsc génère quand même le fichier .js malgré les erreurs. Une erreur de compilation n'est donc pas « bloquante » : c'est à vous de la lire et de la corriger. L'option "noEmitOnError": true empêche cette génération.
  • Annotations et inférence de type

    • Une annotation indique le type explicitement : nom: type.
    • L'inférence: quand une variable est initialisée, TypeScript déduit son type tout seul. Il est inutile, et même déconseillé, d'annoter ce qui est évident.
    let ville = 'Tunis';          // TypeScript devine : string
    const groupe = 'DEV1';        // constante : type littéral 'DEV1'
    const notes = [12, 8, 17];    // number[]
    
    ville = 'Sfax';               // OK : toujours une chaîne
    ville = 2026;
    // error TS2322: Type 'number' is not assignable to type 'string'.
    notes.push('15');
    // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
    • Dans VS Code, survoler une variable avec la souris affiche le type inféré.
    • Bonne pratique :
      • laisser l'inférence travailler pour les variables initialisées ;
      • annoter les paramètres des fonctions (TypeScript ne peut pas les deviner) ;
      • annoter le type de retour des fonctions importantes : il documente et protège.
  • Les types de base

    • Voici les types que vous utiliserez tous les jours. Chacun sera approfondi dans le chapitre suivant.

    Les types de base de TypeScript

    let nom: string = 'Amira';
    let moyenne: number = 15.5;                       // entiers et décimaux : un seul type number
    let admis: boolean = moyenne >= 10;
    let modules: string[] = ['HTML', 'CSS', 'Angular'];
    let coefficients: Array<number> = [3, 2, 1];      // autre écriture de number[]
    let position: [number, number] = [36.8, 10.18];   // tuple : nombre et types fixés par position
    let identifiant: number | string = 'CMD-0142';    // union : l'un OU l'autre
    let niveau: 'debutant' | 'intermediaire' | 'avance' = 'debutant';  // types littéraux
    
    identifiant = 142;        // OK : number fait partie de l'union
    niveau = 'expert';
    // error TS2322: Type '"expert"' is not assignable to type '"avance" | "debutant" | "intermediaire"'.
    • any désactive toute vérification : TypeScript accepte n'importe quoi, même les erreurs. À n'utiliser qu'en dernier recours.
    • unknown signifie « je ne connais pas encore le type » : TypeScript interdit de l'utiliser tant qu'on ne l'a pas vérifié. C'est la version sûre de any, utile pour des données venues de l'extérieur (API, JSON.parse…).
    let libre: any = 5;
    libre.nexistePas();         // aucune erreur à la compilation… plantage à l'exécution
    
    let inconnu: unknown = JSON.parse('{"ok": true}');
    inconnu.ok;
    // error TS18046: 'inconnu' is of type 'unknown'.
    
    if (typeof inconnu === 'object' && inconnu !== null && 'ok' in inconnu) {
      console.log(inconnu.ok);  // OK : le type a été vérifié avant
    }
    1. Typer les fonctions

      • On type chaque paramètre et, après la parenthèse fermante, la valeur de retour. Cela fonctionne avec les fonctions classiques et les fonctions fléchées.
      • Un paramètre optionnel s'écrit avec ?; un paramètre avec valeur par défaut a son type inféré.
      • void indique qu'une fonction ne renvoie rien.
    function moyenneDe(notes: number[]): number {
      return notes.reduce((somme, n) => somme + n, 0) / notes.length;
    }
    
    const presenter = (prenom: string, groupe?: string): string =>
      groupe ? `${prenom} (${groupe})` : `${prenom} (non affecté)`;
    
    function afficherTitre(titre: string, souligne = true): void {
      console.log(titre);
      if (souligne) console.log('-'.repeat(titre.length));
    }
    
    console.log(moyenneDe([12, 8, 17, 15]));                    // 13
    console.log(presenter('Amira', 'DEV1'), presenter('Sami')); // Amira (DEV1) Sami (non affecté)
    afficherTitre('Angular');                                   // Angular puis -------
    • Remarquez que somme et n, dans le callback de reduce, n'ont pas besoin d'annotation : TypeScript sait que notes est un number[].
  • Typer les objets : type et interface

    • Pour décrire la forme d'un objet et la réutiliser, on lui donne un nom :
      • type crée un alias de type: un nom pour n'importe quel type (union, objet…) ;
      • interface décrit la forme d'un objet. C'est l'écriture la plus courante dans Angular pour les données d'une API.
    • Dans une interface : ? rend une propriété optionnelle, readonly l'empêche d'être modifiée.
    type Niveau = 'debutant' | 'intermediaire' | 'avance';
    
    interface Formation {
      readonly id: number;
      titre: string;
      niveau: Niveau;
      places: number;
      prix?: number;            // propriété optionnelle
    }
    
    const angular: Formation = { id: 1, titre: 'Angular', niveau: 'intermediaire', places: 12 };
    const flutter: Formation = { id: 2, titre: 'Flutter', niveau: 'debutant', place: 10 };
    // error TS2561: Object literal may only specify known properties, but 'place' does not exist
    // in type 'Formation'. Did you mean to write 'places'?
    
    angular.places = 11;        // OK
    angular.id = 99;
    // error TS2540: Cannot assign to 'id' because it is a read-only property.
    
    const decrire = (f: Formation): string => `${f.titre} – ${f.niveau} – ${f.prix ?? 'gratuit'}`;
    console.log(decrire(angular));   // Angular – intermediaire – gratuit
    • Une interface n'existe pas dans le JavaScript généré : elle sert uniquement à la vérification, comme toutes les annotations.
    • Remarque : les interfaces, alias, génériques et classes typées font l'objet des chapitres suivants. Ici, l'objectif est de savoir les lire et les écrire simplement.
  • Le fichier tsconfig.json

    • Dès qu'un projet contient plusieurs fichiers, on ne compile plus fichier par fichier : on décrit la configuration dans tsconfig.json, à la racine du projet. La commande npx tsc, sans nom de fichier, lit alors cette configuration.
    • npx tsc --init génère un tsconfig.json commenté avec les options recommandées. Pour ce cours, on utilise la configuration suivante :
    {
      "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./dist",
        "target": "es2022",
        "module": "nodenext",
        "moduleDetection": "force",
        "strict": true,
        "sourceMap": true,
        "types": []
      }
    }

    Un projet TypeScript et son fichier tsconfig.json

    Option Rôle
    rootDir / outDir Dossier des fichiers .ts à compiler / dossier où écrire les .js. On ne modifie jamais le contenu de dist à la main.
    target Version de JavaScript produite. Avec es2022, let, les fonctions fléchées, les classes… sont conservés tels quels.
    module Système de modules (import / export) du code généré. nodenext suit les règles de Node.js.
    moduleDetection Avec force, chaque fichier est un module indépendant : deux fichiers peuvent déclarer une variable de même nom.
    strict Active toutes les vérifications strictes, dont l'interdiction des any implicites et le contrôle de null / undefined. Toujours à true (c'est aussi le cas dans Angular).
    sourceMap Génère des fichiers .js.map qui permettent au débogueur d'afficher le code .ts d'origine.
    types Liste des déclarations de types globales à charger (par exemple ["node"]). Vide ici : on n'en a pas besoin.
    • Le mode strict en action : sans types, les paramètres seraient implicitement de type any, ce qui est refusé.
    function appliquerRemise(prix, taux) {
      return prix - prix * taux;
    }
    // error TS7006: Parameter 'prix' implicitly has an 'any' type.
    // error TS7006: Parameter 'taux' implicitly has an 'any' type.
    1. Compiler en continu et exécuter directement

      • Le mode watch recompile automatiquement à chaque enregistrement d'un fichier. On le laisse tourner dans un terminal pendant qu'on travaille ; Ctrl + C l'arrête.
    npx tsc --watch
    # 07:44:09 AM - Starting compilation in watch mode...
    # 07:44:10 AM - Found 0 errors. Watching for file changes.
    
    node dist/01-bonjour.js     # dans un second terminal
    • On ajoute en général des scripts dans package.json:
    "scripts": {
      "build": "tsc",
      "dev": "tsc --watch"
    }
    • On lance alors npm run build ou npm run dev.
    • Exécution directe: depuis la version 22.18, Node.js sait exécuter un fichier .ts sans compilation préalable. Il se contente d'effacer les types, sans les vérifier :
    node src/01-bonjour.ts      # exécution rapide, mais AUCUNE vérification des types
    npx tsc --noEmit            # vérifie les types sans générer de fichiers
    • Attention : node fichier.ts ne remplace pas tsc. Il n'affiche aucune erreur de type et refuse certaines syntaxes propres à TypeScript, comme les enum (ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX). Utilisez-le pour tester vite, et tsc pour vérifier.
  • TypeScript dans Angular

    • Dans un projet Angular, vous n'appelez jamais tsc vous-même : la commande ng serve (ou ng build) compile le TypeScript, vérifie aussi les templates HTML, puis regroupe le tout en quelques fichiers JavaScript optimisés.
    • Le projet contient déjà ses fichiers tsconfig.json, avec strict activé.

    TypeScript au cœur d'Angular

    • Voici un composant Angular : vous y reconnaissez une interface, des types génériques (signal<Formation[]>), des paramètres typés, et le spread du chapitre précédent :
    import { Component, computed, input, signal } from '@angular/core';
    
    export interface Formation {
      id: number;
      titre: string;
      places: number;
    }
    
    @Component({
      selector: 'app-liste-formations',
      template: `
        <h2>{{ titre() }} ({{ totalPlaces() }} places)</h2>
        @for (f of formations(); track f.id) {
          <p>{{ f.titre }} : {{ f.places }} <button (click)="reserver(f.id)">Réserver</button></p>
        }
      `,
    })
    export class ListeFormations {
      titre = input.required<string>();
    
      formations = signal<Formation[]>([
        { id: 1, titre: 'Angular', places: 12 },
        { id: 2, titre: 'TypeScript', places: 8 },
      ]);
    
      totalPlaces = computed(() => this.formations().reduce((t, f) => t + f.places, 0));
    
      reserver(id: number): void {
        this.formations.update((liste) =>
          liste.map((f) => (f.id === id ? { ...f, places: f.places - 1 } : f)),
        );
      }
    }
    • Grâce aux types, si vous écrivez {{ f.titr }} dans le template ou reserver('1'), l'application ne compile pas: l'erreur est signalée dans le terminal et dans le navigateur, avant qu'un utilisateur ne la rencontre.
    • Version de TypeScript : Angular fixe la version de TypeScript qu'il accepte. Fin 2026, Angular 22 utilise TypeScript 6.0 ; ne mettez donc jamais à jour TypeScript à la main dans un projet Angular, laissez ng update s'en charger.
  • Activité 1 : premier projet TypeScript

    • Dans votre dépôt GitHub, créer le dossier premiers-pas-typescript, puis :
      • initialiser le projet avec npm init -y et installer TypeScript en dépendance de développement ;
      • créer le fichier tsconfig.json du cours (section « Le fichier tsconfig.json ») ;
      • créer un fichier .gitignore contenant node_modules/ et dist/;
      • créer src/01-bonjour.ts avec une fonction fléchée presenterStagiaire qui reçoit prenom, nom et groupe (trois chaînes) et renvoie une chaîne, le nom étant en majuscules.
    console.log(presenterStagiaire('Amira', 'Ben Ali', 'DEV1'));
    console.log(presenterStagiaire('Sami', 'Trabelsi', 'DEV2'));
    
    // Résultat attendu (npx tsc puis node dist/01-bonjour.js) :
    // Amira BEN ALI – groupe DEV1
    // Sami TRABELSI – groupe DEV2
    • Ouvrir dist/01-bonjour.js et le comparer au fichier .ts: qu'est-ce qui a disparu ?
    • Appeler presenterStagiaire('Amira', 'Ben Ali'): noter en commentaire le code et le message de l'erreur obtenue.
  • Activité 2 : lire et corriger les erreurs du compilateur

    • Créer src/02-erreurs.ts avec le code ci-dessous et lancer npx tsc. Le compilateur doit signaler 5 erreurs.
    const formation = { titre: 'Angular', duree: 40, places: 12 };
    
    function reserver(places: number, nombre: number): number {
      return places - nombre;
    }
    
    const restantes: number = reserver(formation.places, '2');
    console.log(`Places restantes : ${restantes}`);
    
    const titreMajuscule = formation.tittre.toUpperCase();
    console.log(titreMajuscule);
    
    let heures: string = formation.duree;
    console.log(reserver(formation.places));
    
    const stagiaires = ['Amira', 'Sami'];
    stagiaires.push(3);
    • Pour chaque erreur, compléter le tableau suivant dans un commentaire en haut du fichier, puis corriger le code jusqu'à obtenir 0 erreur:
    Ligne Code Explication en français Correction
    7 TS2345 ? ?
    ? ? ? ?
    ? ? ? ?
    ? ? ? ?
    ? ? ? ?
    • Avant de corriger, vérifier que dist/02-erreurs.js a quand même été généré. Que se passerait-il en l'exécutant ?
  • Activité 3 : typer un programme JavaScript

    • Voici un programme JavaScript qui gère un catalogue de formations. Le réécrire en TypeScript dans src/03-catalogue.ts:
      • créer un alias Niveau ('debutant' | 'intermediaire' | 'avance') et une interface Formation dont l'id est en lecture seule ;
      • typer le tableau catalogue, ainsi que les paramètres et le retour de chaque fonction.
    const catalogue = [
      { id: 1, titre: 'HTML et CSS', niveau: 'debutant', prix: 250, places: 20, inscrits: 18 },
      { id: 2, titre: 'Angular', niveau: 'intermediaire', prix: 480, places: 15, inscrits: 15 },
      { id: 3, titre: 'TypeScript', niveau: 'intermediaire', prix: 320, places: 12, inscrits: 7 },
      { id: 4, titre: 'Flutter', niveau: 'avance', prix: 550, places: 10, inscrits: 4 },
    ];
    
    const placesRestantes = (f) => f.places - f.inscrits;
    const filtrerParNiveau = (liste, niveau) => liste.filter((f) => f.niveau === niveau);
    const chiffreAffaires = (liste) => liste.reduce((total, f) => total + f.prix * f.inscrits, 0);
    const estComplete = (f) => placesRestantes(f) === 0;
    
    for (const f of catalogue) {
      console.log(`${f.titre} : ${estComplete(f) ? 'complet' : placesRestantes(f) + ' place(s)'}`);
    }
    console.log(filtrerParNiveau(catalogue, 'intermediaire').map((f) => f.titre));
    console.log(`Chiffre d'affaires : ${chiffreAffaires(catalogue).toFixed(3)} DT`);
    
    // Résultat attendu :
    // HTML et CSS : 2 place(s)
    // Angular : complet
    // TypeScript : 5 place(s)
    // Flutter : 6 place(s)
    // [ 'Angular', 'TypeScript' ]
    // Chiffre d'affaires : 16140.000 DT
    • Ajouter l'appel filtrerParNiveau(catalogue, 'expert'): quelle erreur obtenez-vous ? Pourquoi la version JavaScript, elle, renvoyait-elle silencieusement un tableau vide ?
    • Essayer d'écrire catalogue[0].id = 10; et noter l'erreur.
  • Activité 4 : le mode strict et le mode watch

    • Créer src/04-strict.ts:
    function appliquerRemise(prix, taux) {
      return prix - prix * taux;
    }
    console.log(appliquerRemise(480, 0.1));
    console.log(appliquerRemise('480', '10%'));
    • Compiler avec "strict": true, puis avec "strict": false dans tsconfig.json. Noter en commentaire le nombre d'erreurs dans chaque cas, et ce qu'affiche node dist/04-strict.js pour le second appel.
    • Remettre "strict": true, ajouter les scripts build et dev dans package.json, puis lancer npm run dev.
    • Le mode watch étant actif, typer correctement la fonction (paramètres et retour) : observer le terminal à chaque enregistrement jusqu'à « Found 0 errors ». Que devient le second appel ?
    • Enfin, exécuter node src/04-strict.ts sur la version erronée : le programme tourne-t-il ? Qu'en concluez-vous ?
  • Activité 5 : unions et vérification de type

    • Dans src/05-identifiants.ts, écrire :
      • la fonction formaterIdentifiant(id: number | string): string: un nombre devient CMD- suivi du nombre sur 4 chiffres (padStart) ; une chaîne est nettoyée (trim) et mise en majuscules ;
      • la fonction fléchée afficherNote(note: number | null): string: 'absent' si la note vaut null, sinon la note avec deux décimales suivie de / 20.
    console.log(formaterIdentifiant(42));
    console.log(formaterIdentifiant(1250));
    console.log(formaterIdentifiant('  cmd-0007 '));
    console.log(afficherNote(15.5), afficherNote(null));
    
    // Résultat attendu :
    // CMD-0042
    // CMD-1250
    // CMD-0007
    // 15.50 / 20 absent
    • Retirer le test typeof id === 'number' et écrire directement return id.trim().toUpperCase();: quelle erreur obtenez-vous ? Même question en retirant le test note === null.
    • Expliquer en commentaire pourquoi, à l'intérieur du if (typeof id === 'number'), TypeScript accepte que l'on traite id comme un nombre.
    • Faire un commit après chaque activité, puis un push : git commit -m "Présentation de TypeScript : activité N".
  • Erreurs fréquentes

  • Message ou symptôme Cause Solution
    error TS2322: Type 'string' is not assignable to type 'number'. Valeur d'un type différent de celui de la variable Corriger la valeur, ou le type si c'est lui qui est faux
    error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. Argument du mauvais type passé à une fonction Convertir la valeur (Number(x)) ou passer la bonne donnée
    error TS2554: Expected 2 arguments, but got 1. Argument oublié Passer tous les arguments, ou rendre le paramètre optionnel (?) ou par défaut
    error TS2339 / TS2551: Property 'x' does not exist on type … Faute de frappe ou propriété absente du type Corriger le nom (suivre le Did you mean…?) ou compléter l'interface
    error TS7006: Parameter 'x' implicitly has an 'any' type. Paramètre non typé en mode strict Annoter le paramètre : (x: number)
    error TS18047: 'x' is possibly 'null'. Utilisation d'une valeur qui peut valoir null Tester avant : if (x !== null), ou utiliser ?. / ??
    error TS2451: Cannot redeclare block-scoped variable 'x'. Deux fichiers sans import/export partagent la même portée globale Ajouter "moduleDetection": "force" dans tsconfig.json
    tsc : commande introuvable / 'tsc' n'est pas reconnu… TypeScript installé localement mais appelé sans npx Écrire npx tsc, ou passer par un script npm run build
    npx tsc affiche l'aide au lieu de compiler Aucun tsconfig.json dans le dossier courant Se placer à la racine du projet, ou créer le fichier avec npx tsc --init
    Les modifications du .ts n'apparaissent pas à l'exécution On exécute un ancien .js non recompilé Recompiler (npx tsc) ou laisser tourner npx tsc --watch
    Le .js est généré alors que tsc signale des erreurs Comportement par défaut de tsc Corriger toutes les erreurs, ou ajouter "noEmitOnError": true
    1. À retenir

      • TypeScript = JavaScript + un système de types ; tout JavaScript valide est du TypeScript valide.
      • Les types sont vérifiés avant l'exécution par tsc et par l'éditeur, puis effacés: le navigateur ne reçoit que du JavaScript.
      • On annote avec nom: type; l'inférence devine le type des variables initialisées, mais on annote toujours les paramètres.
      • Types de base : string, number, boolean, type[], tuples, unions A | B, types littéraux ; préférer unknown à any.
      • interface et type décrivent la forme des objets ; ? rend une propriété optionnelle, readonly la protège.
      • tsconfig.json configure le projet : npx tsc compile, npx tsc --watch recompile en continu, "strict": true toujours.
      • Dans Angular, le CLI compile tout seul et une erreur de type bloque la compilation.
    TypeScript ne change pas ce que fait votre code : il vérifie ce que vous croyez qu'il fait. Chaque erreur affichée par tsc est un bug qu'aucun utilisateur ne rencontrera.