Home › TypeScript › TypeScript strict mode rules
TypeScript strict mode rules
Cursor rules for strict TypeScript 5.9+: no any, unknown narrowing, discriminated unions, satisfies, and runtime validation.
CursorTypeScript
How to use
Save this as .cursor/rules/typescript.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
Note: Review and test before use. Provided as is, without warranty. See Terms.
.cursor/rules/typescript.mdcDownload ---
description: TypeScript strict mode conventions
globs: ["**/*.{ts,tsx,mts,cts}"]
alwaysApply: false
---
# Strict TypeScript
- Keep `strict: true`, `noUncheckedIndexedAccess`, `noImplicitOverride`, and `exactOptionalPropertyTypes` (if enabled). Never loosen `tsconfig.json` to fix an error.
- No `any`. External data is `unknown` until validated with a schema (zod/valibot) at the boundary; derive types with `z.infer`.
- No non-null assertions (`!`) or `as` casts to silence errors. Narrow with checks, `in`, `instanceof`, or type guards (`function isUser(x: unknown): x is User`). `as const` and `satisfies` are fine.
- Model states as discriminated unions (`{ status: 'loading' } | { status: 'ok'; data: T } | { status: 'error'; error: string }`) and switch exhaustively with a `never` check.
- Prefer `type` aliases for unions and object shapes; `interface` for extendable public contracts. Be consistent with the file.
- Use `readonly` arrays/properties for data that shouldn't change; `Readonly<T>` for params.
- Return types explicit on exported functions.
- Errors: throw `Error` subclasses; in `catch (e)` treat `e` as `unknown`.
- Utility types (`Pick`, `Omit`, `Partial`, `Record`) over duplicating shapes; avoid deeply clever conditional types in app code.
- No `// @ts-ignore`; if unavoidable, `// @ts-expect-error <reason>`.
- `import type` for type-only imports (`verbatimModuleSyntax`).
## Done when
`npx tsc --noEmit` reports zero errors and lint passes.