typescript-patterns

maxbeworks's avatarfrom maxbeworks

TypeScript coding style and patterns - type safety, error handling, code organization

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 8, 2026

When & Why to Use This Skill

This Claude skill provides a comprehensive framework for TypeScript development, focusing on strict type safety, robust error handling, and efficient code organization. It helps developers implement industry-standard patterns like discriminated unions and Result types while avoiding common anti-patterns to ensure high-quality, maintainable, and scalable codebases.

Use Cases

  • Standardizing TypeScript codebases: Use these patterns to enforce consistent coding styles and naming conventions across team projects, reducing technical debt and cognitive load.
  • Enhancing Type Safety: Systematically identify and replace 'any' or 'unknown' types with precise interfaces, enums, and utility types to catch potential bugs at compile-time.
  • Improving Error Resilience: Transition from exception-based error handling to functional Result/Either patterns, ensuring that expected errors are handled explicitly and safely.
  • Optimizing Code Architecture: Apply guidelines for function design, async patterns, and file organization to maintain readability and performance as the project grows.
  • Automated Quality Audits: Serve as a benchmark for reviewing pull requests to detect anti-patterns like nested ternaries, object mutation, or premature abstraction.
nametypescript-patterns
descriptionTypeScript coding style and patterns - type safety, error handling, code organization

Type Safety

  • Never use any - create proper types/enums instead
  • Avoid unknown too - only use in extreme edge cases where you truly can't know the type
  • Leverage existing types with Pick, Omit, Partial, Required rather than creating new ones when possible
  • Use const assertions for literal types: as const
  • Discriminated unions for state/variant management

Enums and Constants

  • Use enums for related constants, then iterate over them instead of hardcoding values
  • Const enums for compile-time optimization
  • Object literals with as const when you need both type and runtime access

Error Handling

  • Return Result/Either types for expected errors, not exceptions
  • Custom error classes with proper typing for unexpected errors
  • Validate at boundaries (API, user input) - trust internal types after that
  • Early returns for error cases - fail fast, avoid deep nesting

Function Design

  • Pure functions when possible - no side effects
  • Early returns over nested conditionals
  • Function declarations for utilities, arrow functions for callbacks
  • Single responsibility as a guideline - use judgment, don't blindly split if it makes code less readable

Code Organization

  • Types that are reused across multiple places go in types/ or similar shared location
  • Types specific to one file/implementation that won't be reused much go at top of file under imports
  • Colocate related implementations
  • Explicit imports over barrel exports (index files)
  • File size guideline is 200-300 lines, but use judgment - split when readability suffers, not by arbitrary line count

Async Patterns

  • Always handle Promise rejections
  • Promise.all() for parallel operations, not sequential awaits
  • Promise.allSettled() when you need all results regardless of failures
  • Don't mix callbacks and Promises

Naming Conventions

  • Booleans: isLoading, hasError, canSubmit, shouldRetry
  • Event handlers: handleClick, handleSubmit (handler implementations)
  • Callbacks: onSubmit, onClick (callback props)
  • Utilities: verb-first (formatDate, parseResponse, validateEmail)
  • Types: PascalCase, purposeful suffixes when needed (UserResponse, CreateUserDto)

Anti-Patterns to Avoid

  • Nested ternaries - use if/else or extract to function
  • Object mutation - use spread or immutable updates
  • Type assertions (as) unless absolutely necessary - fix the types properly
  • Premature abstraction - write it twice before extracting
  • Deep nesting - max 2-3 levels, then extract
  • Magic numbers/strings - use named constants or enums