Kodokon kodokon.com

tsconfig strict : options clés et erreurs courantes

Vous comprenez ce que le mode strict active réellement et savez traiter les erreurs typiques qu'il révèle dans un projet existant.

11 min · 3 questions

Ouvrir cette leçon dans Kodokon

"strict": true n'est pas une option mais un agrégat qui active une famille de vérifications : strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables et alwaysStrict. Chaque nouvelle version de TypeScript peut en ajouter : activer strict vous abonne aux futures vérifications. Chaque drapeau reste désactivable individuellement, ce qui permet une migration progressive sur une base de code existante.

JSON
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "noFallthroughCasesInSwitch": true,
    "exactOptionalPropertyTypes": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true
  }
}
Une base stricte augmentée d'options hors agrégat (fichier JSON).

Les deux drapeaux au plus fort impact sont strictNullChecks et noImplicitAny. Le premier retire null et undefined de tous les types : chaque valeur potentiellement absente doit être déclarée T | undefined et traitée avant usage. Le second refuse qu'un paramètre sans annotation retombe sur any. Ensemble, ils éliminent les deux grandes familles de bugs JavaScript : le « cannot read property of undefined » et la propagation de valeurs non vérifiées. useUnknownInCatchVariables complète le tableau : la variable d'un catch est unknown, car JavaScript autorise de lancer n'importe quoi.

TYPESCRIPT
function findPort(
  env: Record<string, string | undefined>
): number {
  const raw = env["PORT"];
  if (raw === undefined) {
    return 3000;
  }
  return Number.parseInt(raw, 10);
}

declare function riskyOperation(): void;

try {
  riskyOperation();
} catch (err) {
  const message =
    err instanceof Error ? err.message : String(err);
  console.error(message);
}
Deux patterns strict : absence traitée, catch en unknown.

Erreurs courantes en migration, et leurs vrais remèdes. « Object is possibly undefined » : préférez le narrowing (if), l'optional chaining ?. ou un défaut ?? à l'assertion non nulle !, qui ne fait que déplacer le crash. « Property has no initializer » (strictPropertyInitialization) : initialisez dans le constructeur plutôt que de dégainer ! sur le champ. Attention aussi au piège de ?? contre || : port || 3000 remplace aussi 0 et "", alors que port ?? 3000 ne remplace que null et undefined.

TYPESCRIPT
interface Settings { retries?: number }

function resolveRetries(s: Settings): number {
  const bad = s.retries || 3;
  const good = s.retries ?? 3;
  return good;
}

const names = ["Ada", "Linus"];
const first = names[0];
const upper = first?.toUpperCase() ?? "N/A";
retries: 0 donne bad = 3 mais good = 0 ; index vérifié ensuite.

Au-delà de l'agrégat, trois options méritent le débat en équipe. noUncheckedIndexedAccess ajoute undefined à tout accès indexé (arr[i], dict[key]) : plus sûr, mais verbeux sur du code de manipulation de tableaux - beaucoup d'équipes l'adoptent sur les nouveaux projets seulement. exactOptionalPropertyTypes distingue « propriété absente » de « propriété valant undefined », crucial pour les patchs. skipLibCheck ignore la vérification des .d.ts des dépendances : compromis assumé entre temps de build et détection de conflits entre bibliothèques.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Que fait exactement "strict": true dans tsconfig.json ?
    • Il active la seule option strictNullChecks
    • Il active un ensemble de drapeaux stricts, chacun restant désactivable individuellement
    • Il interdit tout usage du type any, y compris explicite
    • Il force la compilation en mode ES5
  2. Avec retries?: number valant 0, quelle est la différence entre retries || 3 et retries ?? 3 ?
    • Aucune, les deux renvoient 0
    • || renvoie 3 car 0 est falsy ; ?? renvoie 0 car il ne remplace que null et undefined
    • ?? renvoie 3 car 0 est considéré comme absent
  3. Pourquoi préférer // @ts-expect-error à // @ts-ignore pour marquer une dette de typage ?
    • @ts-expect-error supprime plusieurs erreurs à la fois
    • @ts-ignore ne fonctionne pas en mode strict
    • @ts-expect-error devient une erreur quand le problème est corrigé, la dette se nettoie donc d'elle-même