Retour au cours

frontend / typescript

Configuration stricte

Leçon 171 exercice

Explication

Ce que vous allez apprendre

  • Comprendre que strict: true regroupe huit vérifications indépendantes, pas un seul interrupteur
  • Identifier ce que fait précisément strictNullChecks, la plus importante de ces vérifications
  • Comprendre strictPropertyInitialization et pourquoi elle protège les champs de classe
  • Découvrir les flags recommandés mais non inclus dans strict (noUncheckedIndexedAccess, exactOptionalPropertyTypes)
  • Savoir lire une erreur de compilation liée au mode strict plutôt que la contourner avec any

Dans quel contexte ?

Un nouveau développeur rejoint une équipe et récupère un projet dont le tsconfig.json a "strict": false. Trois semaines plus tard, une mise en production plante en boutique en ligne : Cannot read properties of undefined (reading 'prix'), parce qu'un produit renvoyé par l'API n'avait pas de champ prix dans un cas particulier. Avec strictNullChecks activé, TypeScript aurait forcé à gérer explicitement ce cas dès l'écriture du code, des mois plus tôt, au lieu de laisser ce bug dormir jusqu'à un scénario de production précis.

Le mode strict n'est pas une option parmi d'autres

strict: true dans le tsconfig.json n'active pas un simple interrupteur, mais un groupe de huit vérifications indépendantes, chacune ciblant une catégorie précise d'erreurs fréquentes. Cette leçon détaille chacune de ces vérifications individuellement, pour comprendre exactement ce qu'on perd en désactivant le mode strict — une pratique à éviter absolument sur un nouveau projet.

Piège fréquent

Désactiver strict (ou un seul de ses flags) pour faire taire rapidement des erreurs de compilation est une fausse économie : chaque erreur supprimée ainsi est un bug potentiel qui réapparaîtra plus tard, en production, sous une forme bien plus coûteuse à diagnostiquer qu'une simple ligne rouge dans l'éditeur.

Les vérifications les plus impactantes au quotidien

strictNullChecks est probablement la plus importante : sans elle, null et undefined sont silencieusement acceptés partout, ce qui est historiquement la source d'erreurs la plus fréquente en JavaScript. strictPropertyInitialization s'assure qu'un champ de classe déclaré est bien initialisé avant d'être utilisé, évitant des undefined inattendus.

Flag de strictCe qu'il empêche concrètement
strictNullChecksnull/undefined acceptés partout sans vérification
noImplicitAnyUn paramètre ou une variable sans type déductible en any
strictPropertyInitializationUn champ de classe jamais initialisé
strictFunctionTypesUn callback incompatible accepté par erreur
useUnknownInCatchVariablesUne variable de catch traitée comme any sans vérification

Des flags recommandés mais non inclus dans strict

Certains réglages utiles ne font volontairement pas partie du groupe strict, car considérés plus contraignants ou plus récents : noUncheckedIndexedAccess force à vérifier qu'un accès par index dans un tableau a bien retourné une valeur avant de l'utiliser, plutôt que de supposer qu'elle existe toujours. exactOptionalPropertyTypes distingue une propriété absente d'une propriété explicitement définie à undefined, une nuance subtile mais parfois importante.

Bonne pratique

Sur un nouveau projet, active strict: true dès le premier commit, avant même d'écrire la première ligne de logique métier. L'ajouter après coup sur un gros projet existant fait souvent apparaître des centaines d'erreurs d'un coup, alors qu'il suffit de les corriger au fil de l'eau quand le flag est actif dès le départ.

Une discipline qui paie sur la durée

Activer ces options peut sembler pénible au début d'un projet, le compilateur signale plus d'erreurs, mais chacune de ces erreurs représente un bug potentiel détecté avant d'atteindre la production. C'est l'investissement de base pour tirer pleinement parti de TypeScript plutôt que de l'utiliser comme un simple habillage syntaxique.

Commandes & code

Configuration stricte

jsonc
// tsconfig.json — chaque flag de "strict" en détail
{
  "compilerOptions": {
    "strict": true, // active tous les flags ci-dessous en une fois

    "noImplicitAny": true,          // interdit les paramètres/variables sans type déductible
    "strictNullChecks": true,       // null et undefined ne sont PAS assignables partout
    "strictFunctionTypes": true,    // vérifie la variance des paramètres de fonction
    "strictBindCallApply": true,    // vérifie les types passés à .bind/.call/.apply
    "strictPropertyInitialization": true, // les champs de classe doivent être initialisés
    "noImplicitThis": true,         // "this" implicite de type "any" interdit
    "alwaysStrict": true,           // émet "use strict" dans le JS généré
    "useUnknownInCatchVariables": true, // "catch (e)" typé "unknown" au lieu de "any"

    // Flags recommandés, NON inclus dans "strict"
    "noUncheckedIndexedAccess": true, // arr[i] retourne T | undefined, pas juste T
    "noImplicitOverride": true,       // "override" obligatoire en cas de redéfinition
    "exactOptionalPropertyTypes": true, // { a?: string } refuse explicitement "a: undefined"
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  }
}
ts
// Effet concret de strictNullChecks
function getLongueur(texte: string | null) {
  // return texte.length; // Error : texte peut être null
  return texte?.length ?? 0; // gestion explicite obligatoire
}

// Effet de noUncheckedIndexedAccess
const notes: number[] = [12, 15, 18];
const note = notes[10]; // typé "number | undefined" et non "number" — force une vérification
if (note !== undefined) {
  console.log(note.toFixed(1));
}

// Effet de strictPropertyInitialization
class Formulaire {
  titre: string; // Error : propriété non initialisée sans "!" ni valeur par défaut
  constructor() {
    this.titre = "Sans titre"; // corrige l'erreur
  }
}

// Effet de noImplicitOverride
class Base {
  sauvegarder(): void {
    /* ... */
  }
}
class Derivee extends Base {
  override sauvegarder(): void {
    /* ... */
  } // "override" requis explicitement
}

// Effet de exactOptionalPropertyTypes
interface Options {
  timeout?: number;
}
// const options: Options = { timeout: undefined }; // Error avec le flag activé
const optionsValide: Options = {}; // "timeout" doit être absent ou un vrai number

Résumé

  • strict: true regroupe 8 flags ; ne jamais le désactiver sur un nouveau projet.
  • noUncheckedIndexedAccess révèle les accès tableau non bornés, une source classique de bugs.
  • exactOptionalPropertyTypes distingue "absent" de "présent mais undefined".

Exercices pratiques

1 disponible
1

Mission : retrouver le bug production avec le mode strict

Objectif : Identifier quel flag du mode strict aurait empêché un plantage en production, puis activer strict et corriger le code concerné.

Contexte

Un projet a "strict": false dans son tsconfig.json. Trois semaines après l'arrivée d'un nouveau développeur, une mise en production plante avec Cannot read properties of undefined (reading 'prix'), un produit renvoyé par l'API n'ayant pas de champ prix dans un cas particulier. Ta mission : comprendre quel flag aurait évité ce bug, puis corriger la configuration et le code.

Résoudre l’exercice →