TypeScript — Claude Code rules
tsconfig
Assume the following flags are on (and don't disable them):
strict: truenoUncheckedIndexedAccess: truenoImplicitOverride: truenoFallthroughCasesInSwitch: truenoUnusedLocals/noUnusedParameters: trueverbatimModuleSyntax: true
Type discipline
- Never introduce
any. If the type is unknown, type it asunknownand narrow. - Prefer union literal types over enums (
type Status = "idle" | "running" | "done"). Enums emit runtime code and have surprising structural behaviour. - Use
satisfiesto keep object literals widely typed while ensuring conformance. asis a last-resort escape hatch. If you need it, add a comment explaining why a narrower form isn't possible.
Patterns
- Discriminated unions for state machines (
{ kind: "loading" } | { kind: "loaded"; data: T }). Result<T, E>style returns instead of throwing for expected failures.- Branded types (
type UserId = string & { __brand: "UserId" }) for IDs that mustn't get mixed up.
Module shape
- Each module exports types alongside the values that use them.
import type { … }for type-only imports (verbatimModuleSyntax enforces this).- Don't re-export everything from a barrel — name the surface explicitly.