Maakaf/friends-activity-backend

Refactoring: Eliminate `any` Type Usage and Improve Type Safety

Open

#76 opened on Nov 8, 2025

 (2 comments) (0 reactions) (0 assignees)TypeScript (17 forks)auto 404
good first issuerefactor

Repository metrics

Stars
 (9 stars)
PR merge metrics
 (PR metrics pending)

Description

The codebase currently contains instances of the any type, which undermines TypeScript's type safety benefits and can lead to runtime errors that could be caught at compile time. This issue tracks the effort to refactor the code to use proper typing throughout the application.

Motivation

  • Type Safety: Using any bypasses TypeScript's type checking, eliminating one of the main benefits of using TypeScript
  • Code Quality: Proper typing improves code readability and maintainability
  • Developer Experience: Better IntelliSense and autocomplete support
  • Error Prevention: Catch type-related bugs at compile time rather than runtime
  • Documentation: Types serve as inline documentation for function signatures and data structures

Scope

We need to audit and refactor the following areas:

1. Service Layer

  • analytics/analytics.service.ts
  • analytics/analytics-report.service.ts
  • pipeline/pipeline.service.ts
  • raw/raw.service.ts
  • All service files in normalized/ subdirectories

2. Repository Layer

  • All *.repo.ts files in analytics/, normalized/ subdirectories
  • Memory repositories (*.memory.repo.ts)

3. Controllers

  • app.controller.ts
  • pipeline/pipeline.controller.ts
  • raw/raw.controller.ts

4. Mappers and Utilities

  • analytics/mappers/map-normalized-to-analytics.ts
  • normalized/mappers.ts
  • normalized/orchestrator.ts

5. Scripts

  • All files in scripts/ directory

Guidelines

  1. Replace any with specific types: Define interfaces or type aliases for complex objects
  2. Use generic types: Where appropriate, use TypeScript generics instead of any
  3. Leverage union types: For values that can be multiple types, use union types (e.g., string | number)
  4. Use unknown for truly unknown types: If you genuinely don't know the type, use unknown instead of any and perform type guards
  5. Define DTOs: Ensure all DTOs are properly typed with class-validator decorators
  6. Type external data: For data from external APIs, define proper interfaces based on API documentation

Acceptance Criteria

  • No usage of any type in the codebase (check with tsc --noImplicitAny)
  • All function parameters and return types are explicitly typed
  • All class properties are typed
  • ESLint rule @typescript-eslint/no-explicit-any is set to "error"
  • All existing tests pass with the new types
  • Update tsconfig.json to include "noImplicitAny": true and "strict": true

Example Refactoring

Before:

function processData(data: any): any {
  return data.map((item: any) => item.value);
}

After:

interface DataItem {
  value: string;
  id: number;
}

function processData(data: DataItem[]): string[] {
  return data.map((item) => item.value);
}

Additional Tasks

  • Add pre-commit hook to prevent any type from being committed
  • Update contributing guidelines to explicitly forbid any type usage
  • Document common type patterns in the project's technical documentation

Note: This is a significant refactoring effort. Consider breaking it down into smaller PRs by module/directory to make reviews manageable.

Contributor guide