Skip to content

Migrate to TypeScript #667

@justin808

Description

@justin808

Background

This tutorial currently uses JavaScript. Migrating to TypeScript would provide better type safety, improved IDE support, and catch more errors at compile time.

Benefits of TypeScript

  • Type safety: Catch type-related bugs at compile time
  • Better IDE support: Enhanced autocomplete, refactoring, and navigation
  • Self-documenting code: Types serve as inline documentation
  • Easier refactoring: Compiler helps identify breaking changes
  • Modern standard: TypeScript is increasingly the standard for React applications

Migration Plan

1. Initial Setup

  • Add TypeScript dependencies to package.json:
    • typescript
    • @types/react
    • @types/react-dom
    • @types/node
    • Other @types/* packages for existing dependencies
  • Create tsconfig.json with appropriate compiler options
  • Update Shakapacker configuration to handle .ts and .tsx files
  • Configure ESLint to work with TypeScript (@typescript-eslint/parser, @typescript-eslint/eslint-plugin)

2. tsconfig.json Example

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "react-jsx",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "allowJs": true,
    "checkJs": false,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "paths": {
      "*": ["client/app/*"]
    }
  },
  "include": ["client/app/**/*"],
  "exclude": ["node_modules", "public", "vendor"]
}

3. Gradual Migration Strategy

  • Start with new files in TypeScript
  • Migrate simple components first (presentational components)
  • Gradually migrate container components
  • Migrate utility files and helpers
  • Add types for Redux store, actions, and reducers
  • Enable stricter TypeScript options incrementally

4. File-by-File Migration Approach

  1. Rename .jsx to .tsx (or .js to .ts)
  2. Add type annotations for props using interfaces
  3. Add type annotations for state
  4. Type function parameters and return values
  5. Fix any TypeScript errors
  6. Run tests to ensure functionality unchanged

5. Key Areas to Type

  • React component props and state
  • Redux actions, reducers, and store
  • API response types
  • Event handlers
  • Utility functions
  • Constants and enums

6. Testing

  • All builds pass with TypeScript enabled
  • Type checking passes (tsc --noEmit)
  • All existing tests still pass
  • IDE provides proper autocomplete and type hints

7. Documentation

  • Update README with TypeScript setup instructions
  • Document typing conventions and patterns used
  • Provide examples of properly typed components

Migration Phases

Phase 1: Setup (Week 1)

  • Install dependencies and configure TypeScript
  • Set up tooling (ESLint, IDE)
  • Create base type definitions

Phase 2: Core Types (Week 2)

  • Type Redux store and actions
  • Type API responses
  • Type common utilities

Phase 3: Component Migration (Weeks 3-4)

  • Migrate simple components
  • Migrate container components
  • Type React Router setup

Phase 4: Refinement (Week 5)

  • Enable stricter compiler options
  • Add generics where beneficial
  • Clean up any any types

Potential Challenges

  1. Learning curve: Team needs to learn TypeScript
  2. Migration time: Converting all files takes time
  3. Third-party types: Some packages may not have good type definitions
  4. ReScript interop: May need special handling for ReScript components
  5. Build time: TypeScript checking may slow down builds

References

Acceptance Criteria

  • TypeScript configuration is complete
  • All builds pass with type checking enabled
  • At least 50% of components migrated to TypeScript
  • CI includes TypeScript type checking
  • Documentation updated

Notes

  • This can be done incrementally - TypeScript supports gradual migration
  • Start with strict: false and enable strict mode features gradually
  • Use allowJs: true to allow mixing .js and .ts files during migration

cc: @justin808

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions