Compiler
Section titled “Compiler”{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "noImplicitOverride": true, "noFallthroughCasesInSwitch": true, "verbatimModuleSyntax": true }}- Extend the framework’s base config (for example Astro’s
strictpreset) and add the flags above. tsc --noEmit(or the framework checker) runs in CI.
- No
any. Useunknownand narrow. A justifiedanyhas a comment. typefor data shapes and unions;interfacefor component props and extendable contracts. Be consistent per project.- Derive types from schemas (
z.infer<typeof schema>) instead of writing them twice. - Use discriminated unions for state (
{ status: 'loading' } | { status: 'error', error } | …). - Avoid enums with runtime output; prefer string-literal unions or
as constobjects.
Boundaries
Section titled “Boundaries”- Validate all external data (API responses, form input, env vars, JSON files) with Zod or similar at the edge.
- Validate environment variables at startup and fail fast.
Tooling
Section titled “Tooling”- ESLint with
typescript-eslint(recommended + type-checked rules) and Prettier; fail CI on warnings. - Path aliases in
tsconfig(@lib/*,@components/*) instead of../../../. - No barrel files re-exporting whole folders in browser code.
- Functions are small and pure where possible; async functions always handle or propagate errors.
- Prefer
readonlyarrays and properties for data that should not change.
Checklist
Section titled “Checklist”- Strict flags on; checker in CI
- No unexplained
any - Types inferred from schemas
- Env vars validated at startup
- ESLint + Prettier clean