TypeScript Best Practices
Follows type-first, functional, and error handling patterns from CLAUDE.md. This skill covers language-specific idioms only.
Pair with React Best Practices
When working with React components (.tsx, .jsx files or @react imports), always load react-best-practices alongside this skill. This skill covers TypeScript fundamentals; React-specific patterns (effects, hooks, refs, component design) are in the dedicated React skill.
Make Illegal States Unrepresentable
Use the type system to prevent invalid states at compile time.
Discriminated unions for mutually exclusive states:
Branded types for domain primitives:
Const assertions for literal unions:
Exhaustive switch with never check:
Runtime Validation with Zod
- Define schemas as single source of truth; infer TypeScript types with
z.infer<>. Avoid duplicating types and schemas. - Use
safeParsefor user input where failure is expected; useparseat trust boundaries where invalid data is a bug. - Compose schemas with
.extend(),.pick(),.omit(),.merge()for DRY definitions. - Add
.transform()for data normalization at parse time (trim strings, parse dates).
Optional: type-fest
For advanced type utilities beyond TypeScript builtins, consider type-fest:
Opaque<T, Token>- cleaner branded types than manual& { __brand }patternPartialDeep<T>- recursive partial for nested objectsReadonlyDeep<T>- recursive readonly for immutable dataSetRequired<T, K>/SetOptional<T, K>- targeted field modificationsSimplify<T>- flatten complex intersection types in IDE tooltips


