Skip to content

[Refactor] Adopt TypeScript for Type-Safe Development Across the Codebase #16

Description

@KarenZita01

Description

The EquipChain backend was initially developed in JavaScript for rapid prototyping. As the codebase grows in complexity with multiple services, middleware, and data access layers, the lack of static typing introduces frequent runtime errors, reduces IDE productivity, and makes refactoring risky. This issue migrates the entire codebase from JavaScript to TypeScript, bringing type safety, better developer experience, and improved code maintainability.

The migration must be performed incrementally to minimize disruption. The approach is: rename all .js files to .ts, introduce TypeScript configuration with strict mode enabled, add type annotations to all function signatures and exported interfaces, create type definition files for external modules that lack them, and configure the build pipeline to compile TypeScript to JavaScript in a dist/ directory. The existing test suite must continue to pass throughout the migration.

Key TypeScript configuration options: strict: true, esModuleInterop: true, outDir: ./dist, rootDir: ./src, target: ES2022, module: NodeNext, moduleResolution: NodeNext, resolveJsonModule: true, declaration: true (for generating .d.ts files). A tsconfig.json at the project root with separate configs for development and production builds. ESLint should be updated with TypeScript-specific rules (@typescript-eslint).

Technical Context & Impact

  • Dependencies: typescript (^5.x), @types/node, @types/express, @types/cors, @types/ws, @types/jsonwebtoken, ts-node (for development), tsx or tsup for build. DevDependencies: @typescript-eslint/eslint-plugin, @typescript-eslint/parser.
  • Architecture: Source files live in src/ (TypeScript), compiled output goes to dist/ (JavaScript). The package.json main field points to dist/index.js. A build script compiles TypeScript, a dev script uses tsx watch for hot-reloading.
  • Impact: This is a high-impact, high-effort refactor. It touches every file in the codebase. The immediate benefit is catching type errors at compile time rather than runtime. Long-term, it enables more confident refactoring and better collaboration in a team setting.

Step-by-Step Implementation Guide

  1. Install TypeScript and Types: Run npm install --save-dev typescript @types/node @types/express @types/cors @types/ws @types/jsonwebtoken tsx. Run npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser for linting.
  2. Create TypeScript Configuration: Write tsconfig.json with strict mode, ES2022 target, NodeNext module resolution, outDir: ./dist, rootDir: ./src, and include: ["src"]. Write tsconfig.build.json extending base with exclude: ["tests"].
  3. Rename and Convert Files: Rename src/index.js to src/index.ts and all other .js files to .ts. Add type annotations to module exports, function parameters, and return types. Create interfaces for key domain models (User, Device, MeterReading, Config, Webhook).
  4. Update package.json Scripts: Modify main to dist/index.js. Add scripts: "build": "tsc -p tsconfig.build.json", "dev": "tsx watch src/index.ts", "start": "node dist/index.js", "test": "tsx --test tests/**/*.test.ts" or use mocha with tsx. Update lint script for TypeScript files.
  5. Fix Type Errors: Run npx tsc --noEmit and fix all type errors. Common fixes: adding @ts-expect-error for unavoidable third-party issues, creating .d.ts files for untyped modules, and ensuring all require() calls are converted to import.
  6. Update Tests: Rename test files to .ts, add type annotations to mocks and test data, ensure test runner supports TypeScript (configure mocha or use vitest).
  7. Update CI/CD: Modify the GitHub Actions workflow (Issue [CI/CD] Set Up GitHub Actions Workflow for Testing, Linting, and Automated Deployment #9) to run the TypeScript build step before tests: npm run build (or npx tsc --noEmit).

Verification & Testing Steps

  1. Run npx tsc --noEmit — verify zero type errors across the entire codebase.
  2. Run npm run build — verify the dist/ directory is created with compiled JavaScript files that mirror the src/ structure.
  3. Run npm start — verify the compiled JavaScript runs correctly and GET / returns the expected response.
  4. Run npm test — verify all existing tests pass with the TypeScript source files.
  5. Run npm run dev — verify the development server starts with hot-reloading and reflects code changes without restart.
  6. Open a .ts file in VS Code and verify IntelliSense provides type completions, and that type errors are highlighted in the editor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions