Règles de codage IA pour les projets TypeScript en mode strict
Règles AGENTS.md pour les projets TypeScript en mode strict qui éliminent les types `any`, imposent des motifs de narrowing et empêchent les agents de compiler du code erroné.
CursorClaude CodeCodexWindsurf TypeScriptNext.js
Placez ceci à la racine de votre dépôt sous le nom AGENTS.md. Le mode strict de TypeScript n’est utile que dans la mesure où des règles empêchent les agents de le contourner avec des casts any et des commentaires @ts-ignore.
AGENTS.md
# Project Rules — TypeScript Strict
## TypeScript configuration- `strict: true` is set in `tsconfig.json`. This enables `noImplicitAny`, `strictNullChecks`, `strictFunctionTypes`, `strictBindCallApply`, `strictPropertyInitialization`, and `noImplicitThis`. Do not disable any of these.- `noUncheckedIndexedAccess: true` is enabled. Array indexing returns `T | undefined`. Always check array access results before using them.- `exactOptionalPropertyTypes: true` is enabled. Do not assign `undefined` to an optional property — omit the property instead.
## Hard rules — no exceptions- NEVER use `any`. Use `unknown` for values of uncertain type and narrow them before use. The single exception is third-party library types that are themselves typed as `any` — wrap and re-export with a proper type.- NEVER use `as T` type assertions unless you add a comment explaining why the compiler cannot infer the type and why the assertion is safe. Prefer type guards.- NEVER use `@ts-ignore` or `@ts-expect-error` without a comment on the same line explaining the exact reason. If you find yourself using these, refactor instead.- NEVER use non-null assertion (`!`) on values that could genuinely be null/undefined at runtime. Write an explicit check or use optional chaining (`?.`).- NEVER widen a type unnecessarily. If a function returns `string`, type it as `string` — not `string | undefined` just to avoid a null check.
## Type design conventions- Model domain errors with discriminated unions, not thrown errors or `null`. Return `{ ok: true; value: T } | { ok: false; error: string }` from fallible operations instead of relying on catch at the call site.- Prefer `type` aliases for unions and intersections; use `interface` for object shapes that may be extended. Be consistent within a file.- Generic constraints should be as narrow as possible: `T extends string` instead of `T extends unknown` when you only use string operations on `T`.- Export only what callers need. Keep internal implementation types unexported unless there is an explicit reason to expose them.
## Narrowing and runtime validation- All external data (API responses, form input, `JSON.parse` output, URL params) must be validated at the boundary with Zod or a type guard before being used as a typed value. Never cast external data with `as MyType` without validation.- Use `satisfies` to validate object literals against a type without widening: `const config = { ... } satisfies Config` instead of `const config: Config = { ... }` when you need to preserve literal types.- Exhaustiveness checks in `switch` statements: add a `default: assertNever(x)` arm where `assertNever` is `(x: never) => never` — this catches unhandled union members at compile time when the union is extended.
## Definition of done- `tsc --noEmit` passes with zero errors.- `grep -r 'as any\|: any\|@ts-ignore\|@ts-expect-error' src/` returns zero results (or every hit has an approved justification comment).- ESLint with `@typescript-eslint/no-explicit-any` and `@typescript-eslint/no-unsafe-*` rules enabled passes.- No `!` non-null assertions on values that come from external data or optional fields.Pourquoi ces règles
- Pas de
as Tsans commentaire est la règle la plus importante après l’interdiction deany. Les assertions de type sont le principal moyen pour les agents de « corriger » les erreurs TypeScript sans les résoudre réellement — le code compile mais la garantie de type à l’exécution disparaît. Exiger une justification écrite oblige les agents à réfléchir à la sécurité réelle de l’assertion. - Valider les données externes à la frontière évite la plus grande classe d’erreurs de type à l’exécution dans les applications TypeScript. Les agents qui voient une réponse API typée font souvent confiance à l’annotation de type sans vérifier si elle a été validée au moment du fetch, produisant des applications où les types TypeScript sont des mensonges qui compilent proprement mais plantent de manière imprévisible.
Bonnes correspondances
- Bases de code TypeScript en production avec
strict: trueoù la sécurité des types est une exigence de qualité de premier ordre — en particulier celles qui traitent des données utilisateur, des transactions financières ou des intégrations d’API externes.
Pas adapté
- Prototypage rapide ou scripts où la sécurité stricte des types ajoute une surcharge sans avantage — utilisez
strict: falseet un ensemble de règles plus léger pour du code jetable.