TypeScript strict : pourquoi je refuse de le désactiver
Le flag strict dans tsconfig.json est contesté sur presque chaque projet. Voici pourquoi je ne cède jamais, et ce que ça change concrètement.
Sur presque chaque projet, la même conversation revient. Quelqu'un ouvre le tsconfig.json et demande : « on peut mettre strict à false ? Ça simplifierait les types. » La réponse est non. Voici pourquoi.
Ce que "strict" active vraiment
Le flag strict n'est pas un seul paramètre — c'est un raccourci qui en active sept simultanément. Les deux qui changent le plus le quotidien :
- noImplicitAny : interdit les types implicitement any. Chaque variable sans type explicite inférable produit une erreur.
- strictNullChecks : null et undefined ne sont pas assignables à un type T. Tout cas null doit être traité explicitement.
- strictFunctionTypes : contrôle de variance sur les types de fonctions.
- strictPropertyInitialization : les propriétés de classe doivent être initialisées dans le constructeur.
- noImplicitThis : this doit être explicitement typé dans les fonctions.
Les cinq autres sont du bruit fin. Les deux premiers — noImplicitAny et strictNullChecks — sont ceux qui font réellement la différence en production.
Les objections classiques
« Ça prend plus de temps d'écrire les types. » Oui, au début. Ce temps est récupéré au premier refactoring important, quand le compilateur trouve les 12 endroits cassés avant que les tests — ou les utilisateurs — ne le fassent.
« On peut l'activer plus tard. » Non. Ajouter strict à un projet existant, c'est corriger des centaines d'erreurs sur du code que personne ne maîtrise plus. C'est toujours plus difficile que prévu, et souvent abandonné à mi-chemin. La dette est là — elle est juste invisible.
Un exemple concret
Voici le type de bug que strictNullChecks attrape à la compilation :
// Sans strictNullChecks — compile, crash en runtime
function getUser(id: string): User {
return users.find(u => u.id === id);
// Type inféré : User | undefined
// TypeScript ne dit rien — et pourtant c'est faux
}
const user = getUser('abc');
console.log(user.name); // TypeError si l'id n'existe pasAvec strictNullChecks, la signature de retour `User` est une erreur de compilation : `Type 'User | undefined' is not assignable to type 'User'`. On est forcé de traiter le cas absent dès l'écriture.
// Avec strictNullChecks — le contrat est honnête
function getUser(id: string): User | undefined {
return users.find(u => u.id === id);
}
const user = getUser('abc');
if (!user) throw new Error(`User ${id} not found`);
console.log(user.name); // TypeScript sait que user est User iciLa vraie question
Le coût de strict est front-loaded — on le paie en début de projet, quand les types sont nouveaux et le code encore malléable. Le bénéfice est long terme : moins de TypeErrors en production, refactorings plus sûrs, onboarding plus rapide pour les développeurs qui rejoignent le projet.
Désactiver strict, c'est prendre une dette technique au premier fichier. Ce n'est pas une question de style — c'est une question de coût différé. Je préfère le payer maintenant.
Un codebase sans strictNullChecks, c'est un codebase qui ment à son propre compilateur.
Écrit par
Casian Ciorba
6 ans de projets livrés en production — logiciels, SaaS, applications mobiles et intégrations IA. J'écris sur ce que j'utilise réellement en mission, pas sur ce qui fait les conférences.