Skip to content

Fix TypeScript ESLint errors (Phase 1): Auto-fixes and simple manual fixes#788

Merged
justin808 merged 1 commit intomainfrom
justin808/fix-ts-eslint-errors
Nov 2, 2025
Merged

Fix TypeScript ESLint errors (Phase 1): Auto-fixes and simple manual fixes#788
justin808 merged 1 commit intomainfrom
justin808/fix-ts-eslint-errors

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Nov 2, 2025

Summary

This PR addresses the first batch of ESLint errors in TypeScript files that were previously suppressed via the ignore pattern package/**/*.ts in eslint.config.js.

Part of #783 - TypeScript ESLint Technical Debt resolution.

Changes Made

Auto-fixes Applied

  • Import ordering and organization (import/order, import/first, import/newline-after-import)
  • Removed unnecessary type assertions (@typescript-eslint/no-unnecessary-type-assertion)

Manual Fixes

  • Replaced @ts-ignore with @ts-expect-error in .d.ts files for webpack optional peer dependency
  • Removed unnecessary @ts-expect-error from runtime .ts files (webpack is installed in dev environment)
  • Replaced any with unknown in loader option interfaces
  • Fixed no-use-before-define error by moving isValidDevServerConfig before isValidConfig

Error Reduction

  • Before: 293 ESLint errors
  • After: 247 ESLint errors
  • Fixed: 46 errors (15.7% reduction)

Testing

  • All existing linting passes with standard ignore patterns
  • TypeScript compilation succeeds (tsc --noEmit)
  • Pre-commit hooks pass (type checking, linting, prettier)

Remaining Work

This is Phase 1 of the ESLint technical debt cleanup. The remaining 247 errors include:

  • @typescript-eslint/no-require-imports (requires ES6 import migration)
  • Various @typescript-eslint/no-unsafe-* violations (require proper typing)
  • @typescript-eslint/no-redundant-type-constituents (type definition improvements)

These will be addressed in subsequent PRs to keep changes focused and reviewable.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Reorganized imports and simplified internal code structure for improved maintainability.
    • Strengthened type safety by replacing permissive type definitions with stricter alternatives.
    • Enhanced validation mechanisms for configuration handling.
  • Chores

    • Updated TypeScript compiler directives for better error detection.
    • Applied minor code formatting improvements.

…fixes

This commit addresses the first batch of ESLint errors in TypeScript files
that were previously suppressed via the ignore pattern `package/**/*.ts`.

Changes:
- Run auto-fix to handle fixable errors (import ordering, unnecessary type assertions, etc.)
- Replace @ts-ignore with @ts-expect-error in .d.ts files for webpack optional peer dependency
- Remove unnecessary @ts-expect-error from runtime .ts files (webpack is installed in dev)
- Replace `any` with `unknown` in loader option interfaces
- Fix no-use-before-define error by moving isValidDevServerConfig before isValidConfig

Error reduction: 293 → 247 errors (46 errors fixed)

Part of issue #783 - TypeScript ESLint Technical Debt resolution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 2, 2025

Walkthrough

This PR modernizes TypeScript import handling and improves type safety across the package. Changes include reorganizing imports with explicit type-only declarations, upgrading any to unknown in type definitions, replacing TypeScript ignore directives with expect-error, adding a new isValidDevServerConfig runtime type guard, refactoring a function to an arrow function, and removing ESLint disable comments.

Changes

Cohort / File(s) Summary
Import reorganization and deduplication
package/dev_server.ts, package/environments/base.ts, package/environments/development.ts, package/environments/test.ts, package/index.ts, package/rspack/index.ts
Reorganized and deduplicated imports; added explicit type-only imports; moved webpack-merge and other runtime imports to follow type import blocks. No functional changes.
Type safety improvements
package/loaders.d.ts, package/webpack-types.d.ts
Replaced @ts-ignore with @ts-expect-error directives; narrowed ShakapackerLoaderOptions index signature from [key: string]: any to [key: string]: unknown for stricter typing.
Formatting and whitespace
package/rules/file.ts, package/rules/jscommon.ts, package/webpackDevServerConfig.ts
Added blank lines after import statements for improved readability. No logic changes.
Logic improvements
package/optimization/webpack.ts, package/utils/helpers.ts, package/utils/typeGuards.ts
Refactored getOptimization to concise arrow function; removed ESLint disable comment; introduced new runtime type guard isValidDevServerConfig(obj: unknown): obj is DevServerConfig with production-only validation and path traversal security checks.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant isValidDevServerConfig
    participant shouldValidate
    participant pathValidator
    
    Caller->>isValidDevServerConfig: Call with unknown obj
    isValidDevServerConfig->>isValidDevServerConfig: Check if obj is object
    alt is object
        isValidDevServerConfig->>shouldValidate: Check validation flag
        alt shouldValidate() returns true
            isValidDevServerConfig->>pathValidator: Run deep validation
            pathValidator->>pathValidator: Validate all path fields
            alt paths valid
                isValidDevServerConfig->>Caller: Return true (type guard passes)
            else paths invalid
                isValidDevServerConfig->>Caller: Return false
            end
        else shouldValidate() returns false
            isValidDevServerConfig->>pathValidator: Run security checks only
            pathValidator->>pathValidator: Validate path traversal safety
            alt security checks pass
                isValidDevServerConfig->>Caller: Return true
            else security checks fail
                isValidDevServerConfig->>Caller: Return false
            end
        end
    else not object
        isValidDevServerConfig->>Caller: Return false
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Most changes are repetitive import reorganization across multiple files with consistent patterns
  • Type safety improvements (anyunknown) are straightforward narrowing operations
  • New isValidDevServerConfig type guard introduces functional logic but remains relatively simple with clear structure
  • Directive replacements (@ts-ignore@ts-expect-error) are mechanical updates

Areas requiring extra attention:

  • package/utils/typeGuards.ts — Verify the new type guard correctly handles all DevServerConfig validation paths and that caching refactors maintain behavior
  • package/environments/base.ts — Confirm the getEntryObject merge logic correctly retains previousPaths without unwanted type coercion

Possibly related issues

Possibly related PRs

Suggested reviewers

  • tomdracz
  • G-Rath

Poem

🐰 Imports now tidy, types more bright,
No more any causing fright,
Guards stand watch with unknown care,
DevServer safe, beyond compare!
Order reigns where chaos was,
Type-safe code without a pause!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Fix TypeScript ESLint errors (Phase 1): Auto-fixes and simple manual fixes" accurately reflects the primary objective of the changeset. The pull request addresses the first batch of TypeScript ESLint errors by applying auto-fixes (import ordering, type assertion removal) and manual corrections (directive changes, type safety improvements). The title is clear, specific, and includes contextual information ("Phase 1") that helps readers understand this is part of a larger effort. It avoids vague language and directly communicates the work being performed across the multiple modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch justin808/fix-ts-eslint-errors

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Nov 2, 2025

Code Review: TypeScript ESLint Phase 1 Fixes

Great work on tackling the ESLint technical debt! This is a well-structured, focused PR that makes meaningful progress. Here's my detailed review:

✅ Strengths

  1. Excellent Incremental Approach: Breaking down 293 errors into manageable phases is the right strategy. A 15.7% reduction (46 errors) in Phase 1 is solid progress.

  2. Import Organization: The import reordering follows best practices:

    • Type-only imports at the top
    • External dependencies before internal ones
    • Proper blank line separation
  3. Type Safety Improvements:

    • Replacing any with unknown in loader options is the correct approach for stricter type safety
    • Removing unnecessary type assertions improves code clarity
    • The @ts-expect-error vs @ts-ignore change is a good practice (fails if the error goes away)
  4. Function Reordering Fix: Moving isValidDevServerConfig before isValidConfig in typeGuards.ts properly resolves the no-use-before-define error while maintaining logical grouping.

🔍 Code Quality Observations

package/utils/typeGuards.ts (lines 73-99, 114, 139, etc.)

  • The function reordering looks good and maintains all functionality
  • All cache operations correctly updated to use obj directly instead of obj as object (lines 114, 139, 147, 151, etc.)
  • This is safe because the WeakMap is already typed as WeakMap<object, CacheEntry>

package/environments/base.ts (line 76)

  • Removed unnecessary type assertion previousPaths as string[]
  • TypeScript can already infer this from the Array.isArray() type guard - good catch!

package/optimization/webpack.ts

  • Simplified arrow function syntax is cleaner
  • Functional change is equivalent, just more concise

🤔 Minor Concerns & Questions

  1. Type Assertion Removal in base.ts (line 77)

    • The assertion previousPaths as string was removed, relying on TypeScript's narrowing
    • This is correct but worth noting: if the Entry type definition changes, this could surface type errors
    • Recommendation: Ensure the Entry type from webpack is well-defined in tests
  2. @ts-expect-error Usage in .d.ts Files

    • Files: loaders.d.ts, webpack-types.d.ts
    • The comment explains webpack is an optional peer dependency
    • Question: Should we verify these errors still exist in CI? @ts-expect-error fails if the error goes away, which is good, but it means the build will break if webpack becomes required
    • Recommendation: Document this behavior or add a test that validates optional peer dependencies
  3. Test Coverage

    • The changes to typeGuards.ts are well-covered by existing tests in test/typescript/securityValidation.test.js
    • Import reordering has no test impact (visual/style only)
    • Recommendation: Consider running the existing test suite as part of the PR validation

🔒 Security Considerations

✅ No security concerns identified. The changes are primarily stylistic and type-safety improvements. The security-critical path validation logic in typeGuards.ts was not modified, only reordered.

⚡ Performance Considerations

✅ No performance impact. The changes are:

  • Import order (no runtime effect)
  • Type annotations (compile-time only)
  • Function reordering (no runtime effect)
  • Removing unnecessary type assertions (micro-optimization, if anything)

🧪 Testing Recommendations

  1. ✅ Verify linting passes: yarn lint
  2. ✅ Verify TypeScript compilation: tsc --noEmit (mentioned in PR description)
  3. Recommended: Run existing test suite to ensure no behavioral changes
    • yarn test or equivalent JavaScript test runner
    • bundle exec rspec for Ruby tests
  4. Recommended: Verify both webpack and rspack configurations still work

📋 CHANGELOG Considerations

Per CLAUDE.md guidelines, this PR should NOT have a CHANGELOG entry because:

  • These are linting/code quality fixes, not user-visible changes
  • No functionality changes
  • Internal refactoring only

This aligns with the project's guidelines: "Do NOT add changelog entries for: linting fixes, code formatting, internal refactoring"

🎯 Summary

Approval Status: ✅ Approved with minor recommendations

This is solid work that improves code quality without introducing risk. The incremental approach is commendable.

Before merge, consider:

  1. Running the full test suite to validate no behavioral changes
  2. Verifying both webpack and rspack configurations build successfully

For future phases, watch out for:

  • The @typescript-eslint/no-require-imports fixes (will need careful migration to ES6 imports)
  • The no-unsafe-* violations (these may require more significant type definitions)

Great job on maintaining focus and keeping changes reviewable! 🚀


Review generated with Claude Code

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
package/loaders.d.ts (1)

4-6: Consider consolidating duplicate interface definitions.

The ShakapackerLoaderOptions interface is defined identically in both package/loaders.d.ts (lines 4-6) and package/webpack-types.d.ts (lines 15-17). Consider extracting this to a shared types file to maintain a single source of truth.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64eb2f2 and 65c6c91.

📒 Files selected for processing (14)
  • package/dev_server.ts (1 hunks)
  • package/environments/base.ts (2 hunks)
  • package/environments/development.ts (1 hunks)
  • package/environments/test.ts (1 hunks)
  • package/index.ts (0 hunks)
  • package/loaders.d.ts (1 hunks)
  • package/optimization/webpack.ts (1 hunks)
  • package/rspack/index.ts (1 hunks)
  • package/rules/file.ts (1 hunks)
  • package/rules/jscommon.ts (1 hunks)
  • package/utils/helpers.ts (0 hunks)
  • package/utils/typeGuards.ts (10 hunks)
  • package/webpack-types.d.ts (2 hunks)
  • package/webpackDevServerConfig.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • package/index.ts
  • package/utils/helpers.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-19T00:36:13.668Z
Learnt from: CR
Repo: shakacode/shakapacker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-19T00:36:13.668Z
Learning: Applies to lib/shakapacker/**/*.rb : When modifying core Shakapacker functionality, test changes with both webpack and rspack bundlers

Applied to files:

  • package/webpack-types.d.ts
  • package/rspack/index.ts
  • package/environments/development.ts
  • package/loaders.d.ts
🧬 Code graph analysis (2)
package/utils/typeGuards.ts (2)
package/types.ts (1)
  • DevServerConfig (65-107)
package/utils/pathValidation.ts (2)
  • validatePort (190-208)
  • isPathTraversalSafe (11-26)
package/loaders.d.ts (1)
package/webpack-types.d.ts (1)
  • ShakapackerLoaderOptions (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Testing (ubuntu-latest, 22.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Testing (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: claude-review
  • GitHub Check: test
🔇 Additional comments (17)
package/webpackDevServerConfig.ts (1)

2-2: LGTM! Import formatting improved.

The blank line after the import statement improves readability and satisfies ESLint's import organization rules.

package/rspack/index.ts (1)

10-11: LGTM! Import ordering improved.

Moving the webpack-merge require after type imports aligns with ESLint import ordering rules while preserving all functionality.

package/rules/file.ts (1)

2-2: LGTM! Import formatting improved.

The blank line after the import statement enhances readability and satisfies ESLint's import organization rules.

package/rules/jscommon.ts (1)

3-3: LGTM! Import formatting improved.

The blank line after the import statement improves code consistency and satisfies ESLint's import organization rules.

package/environments/base.ts (2)

4-6: LGTM! Type imports improved.

Adding explicit imports for Dirent, Configuration, and Entry types enhances type safety and makes dependencies clear.


75-77: LGTM! Logic improvement for array handling.

The updated logic correctly preserves previousPaths when it's already an array, avoiding an unnecessary array reconstruction. This is more efficient and clearer than the previous approach.

package/environments/development.ts (1)

13-19: LGTM! Import organization improved.

Reordering runtime imports to follow type-only imports aligns with ESLint's import ordering rules and improves code consistency across the codebase.

package/dev_server.ts (1)

2-3: LGTM! Import deduplication improved.

Adding the explicit top-level import of DevServerConfig and removing the duplicate import elsewhere improves code organization and clarity.

package/optimization/webpack.ts (1)

22-51: LGTM! Concise arrow function syntax.

The refactor from a function declaration with an explicit return to an arrow function with an implicit return is clean and idiomatic. The behavior remains identical—same optimization configuration and minimizer setup.

package/environments/test.ts (1)

6-7: LGTM! Import organization improved.

The type-only import has been appropriately moved to the top of the file, aligning with ESLint import ordering rules.

package/utils/typeGuards.ts (3)

69-99: LGTM! Well-structured runtime type guard.

The new isValidDevServerConfig function appropriately validates DevServerConfig objects with production-optimized minimal validation. The implementation correctly uses shouldValidate() to skip deep validation in production for performance while maintaining type safety.


114-114: LGTM! Unnecessary type assertions removed.

The as object casts have been appropriately removed from validatedConfigs.get() and .set() calls. Since obj is already validated as an object at line 109, these assertions were redundant.

Also applies to: 139-139, 151-151, 174-174, 185-185, 199-199, 211-211, 221-221, 235-235, 244-244


147-147: The code is correct—TypeScript properly narrows the indexed access type.

The typeof check at line 137 (if (typeof config[field] !== "string")) with its early return ensures that by line 147, TypeScript's control flow analysis narrows config[field] to string. Modern TypeScript (5.9.x) with strict mode handles this pattern correctly for indexed access on Record<string, unknown>, so the explicit as string assertion is unnecessary.

The fact that tsc --noEmit compiles without errors for this pattern confirms the code is valid.

package/loaders.d.ts (2)

1-1: LGTM! Better error suppression directive.

Replacing @ts-ignore with @ts-expect-error is the correct approach for suppressing expected TypeScript errors. This directive will fail if the error is resolved, preventing stale suppressions.


5-5: LGTM! Type safety improved.

Changing from any to unknown for the index signature improves type safety by requiring explicit type checking before using values.

package/webpack-types.d.ts (2)

1-1: LGTM! Better error suppression directive.

Replacing @ts-ignore with @ts-expect-error ensures that the suppression will fail if the error is resolved in the future, preventing accumulation of stale directives.


16-16: LGTM! Type safety improved.

Narrowing the index signature from any to unknown requires explicit type checking before use, improving type safety throughout the codebase.

@justin808 justin808 merged commit f81f6e5 into main Nov 2, 2025
55 checks passed
@justin808 justin808 deleted the justin808/fix-ts-eslint-errors branch November 2, 2025 19:46
justin808 added a commit that referenced this pull request Nov 2, 2025
…#793)

## Summary

This PR addresses simple, safe ESLint fixes that don't change any
runtime behavior or APIs.

Part of #789 - TypeScript ESLint Phase 2a: Simple Non-Breaking Fixes
Related to #783 - TypeScript ESLint Technical Debt resolution
Follows PR #788 - Phase 1 completion

## Changes Made

### 1. Remove Unused ESLint Directives (4 errors)
**File:** `package/utils/debug.ts`

Removed unused `// eslint-disable-next-line no-console` comments. These
directives are no longer needed since the `no-console` rule is not
triggering for these console methods in a debug utility module.

**Impact:** Cleanup only - no functional changes

### 2. Fix Explicit `any` Types (4 errors)
**Files:**
- `package/utils/getStyleRule.ts` - Replaced `any[]` with `unknown[]`
for loader arrays
- `package/utils/helpers.ts` - Replaced `error: any` with `error:
unknown` and added proper type assertion
- `package/utils/requireOrError.ts` - Replaced `any` return type with
`unknown`

**Impact:** Internal only - improves type safety without changing
behavior

### 3. Fix Redundant Type Constituents (19 errors)
**Files:**
- `package/types.ts` - Simplified `DevServerConfig` interface type
unions
- `package/webpackDevServerConfig.ts` - Simplified webpack dev server
config type unions

**Examples:**
```typescript
// Before:
allowed_hosts?: "all" | "auto" | string | string[]
host?: "local-ip" | "local-ipv4" | "local-ipv6" | string
port?: "auto" | string | number
static?: boolean | string | unknown
watch_files?: string | string[] | unknown

// After:
allowed_hosts?: string | string[]
host?: string
port?: string | number
static?: unknown
watch_files?: unknown
```

**Reasoning:**
- When a union includes `string`, specific string literals like `"all"`
or `"auto"` are redundant because `string` already includes all possible
strings
- When a union includes `unknown`, all other types are redundant because
`unknown` is the top type that includes everything

**Impact:** Type definitions become cleaner and more accurate. No
runtime changes, no API changes.

## Error Reduction

- **Before**: 247 ESLint errors
- **After**: 220 ESLint errors
- **Fixed**: 27 errors (10.9% reduction)

## Testing

- ✅ All existing linting passes with standard ignore patterns
- ✅ TypeScript compilation succeeds (`tsc --noEmit`)
- ✅ Pre-commit hooks pass (type checking, linting, prettier)
- ✅ Security validation tests pass
- ⚠️ Some build tests fail, but these failures exist on main and are
unrelated to these changes

## Remaining Work

After this PR:
- **220 errors remaining** (down from original 293)
- **Next**: Phase 2b - Type Safety Improvements (~94 errors) - Issue
#790

## Related Issues and PRs

- #783 - Parent issue: TypeScript ESLint Technical Debt
- #789 - This issue: Phase 2a Simple Fixes
- #788 - Phase 1 completion (46 errors fixed)
- #790 - Phase 2b: Type Safety Improvements (next step)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Refined type constraints and annotations across configuration and
utility modules for improved type safety.
  * Simplified error handling with more precise type definitions.
  * Removed unnecessary linting directives from utility functions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant