TheThingsNetwork / lorawan-stack

The Things Stack, an Open Source LoRaWAN Network Server
https://www.thethingsindustries.com/stack/
Apache License 2.0
974 stars 305 forks source link

Migrate the frontend codebase to TypeScript #7329

Open kschiffer opened 3 days ago

kschiffer commented 3 days ago

Summary

This issue proposes migrating our Console and Account applications from JavaScript to TypeScript. Utilizing TypeScript will provide significant benefits, including improved type safety, enhanced code maintainability, and a better developer experience, particularly as our applications continue to grow in complexity. Also, it enables us to be future proof for React 19.

Current Situation

Currently, both the Console and Account applications are entirely in JavaScript. While we utilize propTypes and defaultProps for rudimentary type checking. This approach is deprecated and set to be removed starting from React 19 Also, this approach is limited and doesn't offer the full benefits of static type checking. This can lead to potential runtime errors and negatively impacts code clarity and readability, especially when working with complex data structures and interactions between components and the Redux store.

Why do we need this? Who uses it, and when?

Migrating to TypeScript will primarily benefit the developers working on these codebases. It offers several advantages:

Proposed Implementation

We will follow a gradual migration approach, gradually converting sections of the codebase to TypeScript to minimize disruption and ensure continuous integration and deployment:

Phase 1: Setting the Stage

  1. Install Dependencies: Install TypeScript and the necessary type definitions for React and Redux: npm install -D typescript @types/react @types/react-dom @types/react-redux
  2. Configuration:
    • Create a tsconfig.json file for both Console and Account, initially setting the strict option to false to allow for a smoother initial conversion.
    • Update Webpack/Babel configurations to handle TypeScript files (.ts and .tsx).
    • Configure ESLint with TypeScript support and adjust linting rules to support both JavaScript and TypeScript during the transition.
  3. Data Structures: Define TypeScript interfaces for key data structures shared across the applications:
    • API responses (e.g., gateway, application, device, etc.)
    • State objects used within Redux reducers
    • Complex prop types passed between components

Phase 2: Picking the Low-Hanging Fruit

  1. Simple Components: Convert basic, stateless components to TypeScript, starting with those primarily relying on props and having minimal logic. Examples include:
    • ./components/tabs/index.js
    • ./components/tabs/tab/index.js
    • ./components/sidebar/switcher/index.js
    • ./components/sidebar/search-button/index.js
    • ./components/sidebar/section-label/index.js
    • ./components/sidebar/side-footer/index.js
    • ./components/sidebar/side-header/index.js
    • ./components/sidebar/side-menu/item/link.js
  2. Redux Actions and Reducers: These highly benefit from type definitions, ensuring type safety throughout state management.
  3. Utility Functions: Migrate utility functions with well-defined input and output types to TypeScript. Examples include:
    • ./lib/to-input-date.js
    • ./lib/filter-data-props.js
    • ./lib/password/index.js
    • ./lib/combine-refs.js
    • ./lib/string-to-hash.js
    • ./lib/host-from-url.js
    • ./lib/debounce.js
    • ./lib/get-by-path.js
    • ./lib/capitalize-message.js
    • ./lib/pipe.js

Phase 3: Tackling the Core

  1. Stateful Components: Convert more complex, stateful components to TypeScript.
  2. Containers/Connectors: Introduce types for containers and connectors, ensuring type safety between components and the Redux store.
  3. API Client: Define interfaces for API endpoints and responses in both Console and Account applications, promoting consistent data handling.
  4. Third-Party Libraries: Utilize existing type definitions from DefinitelyTyped where available. Create custom definitions for external libraries lacking official TypeScript support.

Phase 4: Increasing Type Strictness & Refactoring

  1. Thorough Review: Once a substantial portion of the codebase is migrated, review existing type definitions for accuracy and completeness.
  2. Stepping Up the Strictness: Gradually adjust tsconfig.json to increase type strictness levels. This helps catch potential errors and enforce better coding practices.
  3. Guided Refactoring: Utilize TypeScript's robust type system to guide refactoring efforts, identifying areas for code improvement and further reducing potential errors.

Specific Examples and Considerations

By following this phased approach, we can leverage TypeScript's strengths to significantly enhance the reliability, maintainability, and overall developer experience of our Console and Account applications.

Contributing

Validation

Code of Conduct

kschiffer commented 3 days ago

Blocked by #7328