P PasteCode
Regla

Reglas de codificación AI para proyectos TypeScript estrictos

Reglas de AGENTS.md para proyectos TypeScript en modo estricto que eliminan tipos any, imponen patrones de estrechamiento y evitan que los agentes compilen código incorrecto.

CursorClaude CodeCodexWindsurf TypeScriptNext.js
.md .json Actualizado 8 jun 2026

Coloca esto en la raíz de tu repositorio como AGENTS.md. El modo estricto de TypeScript solo es tan útil como las reglas que eviten que los agentes lo burlen con casts any y comentarios @ts-ignore.

AGENTS.md

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.

Por qué estas reglas

  • No as T sin un comentario es la regla más importante después de prohibir any. Las aserciones de tipo son la forma principal en que los agentes “arreglan” errores de TypeScript sin realmente arreglarlos — el código compila pero la garantía de tipo en tiempo de ejecución desaparece. Exigir una justificación escrita obliga a los agentes a razonar sobre si la aserción es realmente segura.
  • Validar datos externos en el límite previene la clase más amplia de errores de tipo en tiempo de ejecución en aplicaciones TypeScript. Los agentes que ven una respuesta de API tipada a menudo confían en la anotación de tipo sin verificar si fue validada al momento de la obtención, produciendo aplicaciones donde los tipos TypeScript son mentiras que compilan limpiamente pero fallan de forma impredecible.

Buen ajuste

  • Bases de código TypeScript de producción con strict: true donde la seguridad de tipos es un requisito de calidad de primera clase — especialmente aquellas que manejan datos de usuario, transacciones financieras o integraciones de API externas.

No es adecuado

  • Prototipado rápido o scripts donde la seguridad estricta de tipos añade sobrecarga sin beneficio — usa strict: false y un conjunto de reglas más ligero para código desechable.