TypeScript Refactor Best Practices
Comprehensive TypeScript and TSX refactoring and modernization guide designed for AI agents and LLMs. Contains 47 rules across 9 categories, prioritized by impact to guide automated refactoring, code review, and code generation. Current to TypeScript 6.0 and React 19.
When to Apply
Reference these guidelines when:
- Refactoring TypeScript or React/TSX code for type safety and maintainability
- Designing type architectures (discriminated unions, branded types, generics)
- Narrowing types to eliminate unsafe
ascasts - Typing React components and hooks (props, refs, events, state) in
.tsxfiles - Adopting modern TypeScript 5.x–6.0 features (
satisfies,using, const type parameters, inferred type predicates, erasable syntax,withimport attributes) - Optimizing compiler performance in large codebases (
isolatedDeclarations, project references) - Implementing type-safe error handling patterns
- Reviewing code for TypeScript quirks and pitfalls
Rule Categories by Priority
Quick Reference
1. Type Architecture (CRITICAL)
arch-discriminated-unions[blocked] — Use discriminated unions over string enums for exhaustive pattern matchingarch-branded-types[blocked] — Use branded types for domain identifiers to prevent value mix-upsarch-satisfies-over-annotation[blocked] — Usesatisfiesfor config objects to preserve literal typesarch-interfaces-over-intersections[blocked] — Extend interfaces instead of intersecting types for better error messagesarch-const-assertion[blocked] — Useas constfor immutable literal inferencearch-readonly-by-default[blocked] — Default to readonly types for function parameters and return valuesarch-avoid-partial-abuse[blocked] — AvoidPartial<T>abuse for builder patterns
2. Type Narrowing & Guards (CRITICAL)
narrow-custom-type-guards[blocked] — Replaceaswith runtime-checked guards; TS 5.5+ infers the predicatenarrow-assertion-functions[blocked] — Use assertion functions for precondition checksnarrow-exhaustive-switch[blocked] — Enforce exhaustive switch withnevernarrow-in-operator[blocked] — Narrow with theinoperator for interface unionsnarrow-eliminate-as-casts[blocked] — Eliminateascasts with proper narrowing chains
3. Modern TypeScript (HIGH)
modern-using-keyword[blocked] — Use theusingkeyword for resource cleanupmodern-const-type-parameters[blocked] — Use const type parameters for literal inferencemodern-template-literal-types[blocked] — Use template literal types for string patternsmodern-noinfer-utility[blocked] — UseNoInferto control type parameter inferencemodern-verbatim-module-syntax[blocked] — EnableverbatimModuleSyntaxfor explicit import typesmodern-erasable-syntax[blocked] — Prefer erasable syntax over enums and namespaces for type-strippingmodern-import-attributes[blocked] — Usewithimport attributes instead of deprecatedassert
4. React & TSX (HIGH)
tsx-avoid-react-fc[blocked] — Type props directly instead ofReact.FCtsx-ref-as-prop[blocked] — Passrefas a prop instead offorwardRef(React 19)tsx-extend-native-props[blocked] — Extend native element props withComponentPropsWithRefinstead of redeclaring themtsx-discriminated-props[blocked] — Model mutually-exclusive props as discriminated unionstsx-event-handler-types[blocked] — Type event handlers with React synthetic event typestsx-hook-typing[blocked] — TypeuseState/useReffor nullable and mutable state
5. Generic Patterns (HIGH)
generic-constrain-dont-overconstrain[blocked] — Constrain generics minimallygeneric-avoid-distributive-surprises[blocked] — Control distributive conditional typesgeneric-mapped-type-utilities[blocked] — Build custom mapped types for repeated transformationsgeneric-return-type-inference[blocked] — Preserve return type inference in generic functions
6. Compiler Performance (MEDIUM-HIGH)
compile-explicit-return-types[blocked] — Add explicit return types to exported functionscompile-avoid-deep-recursion[blocked] — Avoid deeply recursive type definitionscompile-project-references[blocked] — Use project references for monorepo buildscompile-base-types-over-unions[blocked] — Use base types instead of large union typescompile-isolated-declarations[blocked] — EnableisolatedDeclarationsfor parallel declaration emit
7. Error Safety (MEDIUM)
error-result-type[blocked] — Use Result types instead of thrown exceptionserror-exhaustive-error-handling[blocked] — Use exhaustive checks for typed error variantserror-typed-catch[blocked] — Type catch clause variables asunknownerror-discriminated-error-unions[blocked] — Model domain errors as discriminated unions
8. Runtime Patterns (MEDIUM)
perf-union-literals-over-enums[blocked] — Use union literals instead of enums — enums are non-erasableperf-avoid-delete-operator[blocked] — Avoid thedeleteoperator on objectsperf-object-freeze-const[blocked] — UseObject.freezewithas constfor true immutabilityperf-object-keys-narrowing[blocked] — AvoidObject.keystype wideningperf-map-set-over-object[blocked] — UseMapandSetover plain objects for dynamic collections
9. Quirks & Pitfalls (LOW-MEDIUM)
quirk-excess-property-checks[blocked] — Understand excess property checks on object literalsquirk-empty-object-type[blocked] — Avoid the{}type — it means non-nullishquirk-structural-typing-escapes[blocked] — Guard against structural typing escape hatchesquirk-variance-annotations[blocked] — Use variance annotations to document generic intent (not for speed)
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions [blocked] — Category structure and impact levels
- Rule template [blocked] — Template for adding new rules


