Le mode strict de TypeScript, c'est l'option "strict": true du tsconfig.json qui active l'ensemble des vérifications de types renforcées. On l'active sur 100% de nos projets, sans exception. On déroule le pourquoi, et les règles qu'on configure dès le premier commit.
- Le mode strict attrape à la compilation les erreurs qui explosent sinon en production : null pointer, propriété manquante, type incorrect.
- Au-delà de
strict, trois options ferment les angles morts :noUncheckedIndexedAccess,exactOptionalPropertyTypes,noImplicitReturns. - Toute donnée externe passe par une validation Zod à la frontière : le type-check ne protège pas du runtime.
tsc --noEmittourne sur chaque PR : un type-check cassé ne merge pas.
Pourquoi le mode strict n'est pas optionnel#
TypeScript sans "strict": true, c'est TypeScript avec les mains attachées. Les erreurs les plus communes en production (null pointer, type incorrect dans un appel API, propriété manquante) sont exactement ce que le mode strict attrape.
Depuis qu'on l'active systématiquement, les bugs liés à un null ou undefined non géré ont pratiquement disparu de nos projets.
Notre tsconfig.json de base#
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "bundler",
"allowImportingTsFiles": true,
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }],
"paths": { "@/*": ["./src/*"] }
}
}Les options importantes au-delà de strict :
noUncheckedIndexedAccess#
const arr = ['a', 'b', 'c']
const first = arr[0] // Type : string | undefined (pas string)
// ✅ Force à gérer le cas undefined
if (first) console.log(first.toUpperCase())exactOptionalPropertyTypes#
interface Config {
timeout?: number
}
// ❌ Erreur avec exactOptionalPropertyTypes
const config: Config = { timeout: undefined }
// ✅ Correct
const config: Config = {}Les patterns qui éliminent les erreurs runtime#
1. Never trust external data sans validation#
import { z } from 'zod'
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
role: z.enum(['admin', 'user', 'viewer']),
})
// À la frontière API
export async function getUser(id: string) {
const raw = await db.users.findUnique({ where: { id } })
return UserSchema.parse(raw) // Lance une erreur si invalide
}2. Result types plutôt que try/catch partout#
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E }
async function fetchUser(id: string): Promise<Result<User>> {
try {
const user = await getUser(id)
return { ok: true, value: user }
} catch (err) {
return { ok: false, error: err instanceof Error ? err : new Error(String(err)) }
}
}
// À l'usage
const result = await fetchUser(id)
if (!result.ok) {
console.error(result.error.message)
return
}
console.log(result.value.email) // TypeScript sait que c'est User ici3. satisfies pour les objets de config#
const routes = {
home: '/',
blog: '/blog',
contact: '/contact',
} satisfies Record<string, `/${string}`>
// ✅ TypeScript vérifie le type sans perdre l'inférence littérale
routes.home // Type : '/'En CI/CD#
# .github/workflows/ci.yml
- name: TypeScript check
run: npx tsc --noEmittsc --noEmit s'exécute sur chaque PR, intégré à notre pipeline CI/CD GitHub Actions. Un PR qui casse le type-check ne merge pas, point.
Conclusion#
Le mode strict n'est pas un obstacle, c'est un filet de sécurité. Les quelques heures de migration sur un projet existant sont largement rentabilisées dès la première semaine. C'est l'un des standards non négociables de notre approche du développement web, au même titre que les Core Web Vitals au vert.
Questions fréquentes
Qu'est-ce que le mode strict de TypeScript ?
Le mode strict (strict: true dans tsconfig.json) active un ensemble de vérifications renforcées : null checks, types implicites interdits, vérifications d'appels de fonction. Il attrape à la compilation les erreurs qui, sinon, explosent en production.
Activer le mode strict sur un projet existant, c'est long ?
Quelques heures sur un projet de taille moyenne, en corrigeant les erreurs fichier par fichier. L'investissement est rentabilisé très vite : chaque erreur corrigée à la migration est un bug potentiel de production éliminé.
Quelles options ajouter au-delà de strict: true ?
Les plus rentables : noUncheckedIndexedAccess (les accès par index retournent T | undefined), exactOptionalPropertyTypes (interdit undefined explicite sur les propriétés optionnelles) et noImplicitReturns. Elles ferment les angles morts que strict laisse ouverts.
Le mode strict ralentit-il le développement ?
Au début, légèrement : il force à gérer les cas null et undefined. Très vite, c'est l'inverse : l'autocomplétion devient fiable, les refactorings sont sûrs et on passe moins de temps à déboguer en production.