P PasteCode
Rule

Regras de Codificação para IA em Projetos TypeScript Strict

Regras do AGENTS.md para projetos TypeScript em modo strict que eliminam tipos any, aplicam padrões de narrowing e impedem que agentes compilem código que está errado.

CursorClaude CodeCodexWindsurf TypeScriptNext.js
.md .json Atualizado 8 de jun. de 2026

Coloque isso na raiz do seu repositório como AGENTS.md. O modo strict do TypeScript é tão útil quanto as regras que impedem agentes de derrotá-lo com casts any e comentários @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 que essas regras

  • as T sem comentário é a regra mais importante depois de banir any. As asserções de tipo são a principal maneira pela qual agentes “corrigem” erros do TypeScript sem realmente corrigi-los — o código compila, mas a garantia de tipo em tempo de execução desaparece. Exigir uma justificativa escrita força os agentes a raciocinar sobre se a asserção é realmente segura.
  • Validar dados externos na fronteira evita a classe mais ampla de erros de tipo em tempo de execução em aplicações TypeScript. Agentes que veem uma resposta de API tipada frequentemente confiam na anotação de tipo sem verificar se ela foi validada no momento da requisição, produzindo aplicações onde os tipos TypeScript são mentiras que compilam perfeitamente, mas falham de forma imprevisível.

Adequado para

  • Bases de código TypeScript de produção com strict: true onde a segurança de tipo é um requisito de qualidade de primeira linha — especialmente aquelas que lidam com dados de usuário, transações financeiras ou integrações com APIs externas.

Não adequado para

  • Prototipagem rápida ou scripts onde a segurança estrita de tipo adiciona sobrecarga sem benefício — use strict: false e um conjunto de regras mais leve para código descartável.