Skip to content

Conversation

@Yeom-JinHo
Copy link
Contributor

@Yeom-JinHo Yeom-JinHo commented Nov 26, 2025

close #1537

Descriptio

This PR fixes a mismatch between the runtime behavior and TypeScript types of toCamelCaseKeys, especially for uppercase keys (e.g. FIRST_NAME, LAST).

At runtime, camelCase('LAST') correctly returns last, but the type-level transformation previously inferred lAST. This caused TypeScript to report incorrect key names in the resulting object type.

The PR also extends the test suite and documentation so that the behavior of toCamelCaseKeys is clearly specified and protected against regressions.

Changes

  • Updated the PascalToCamel utility type to:
    • Detect uppercase keys (S extends Uppercase<S>) and transform them to fully lowercase (Lowercase<S>), aligning with the runtime camelCase behavior.
    • Preserve the existing “lowercase only the first letter” behavior for regular PascalCase keys (e.g. UserIduserId, ApiTokenapiToken).
  • Added tests to cover:
    • Uppercase keys at both runtime and type level
      • e.g. { FIRST_NAME: 'JinHo', LAST: 'Yeom' }{ firstName: 'JinHo', last: 'Yeom' }
    • Non-plain objects to verify we camel-case the property keys but do not recurse into values like Date, Map, Set, etc.
  • Updated the toCamelCaseKeys documentation with:
    • An explicit note that snake_case, PascalCase, and uppercase keys are all converted to camelCase.
    • An additional example showing how mixed PascalCase and uppercase keys are converted.

Motivation

  • Runtime and type-level behavior should be consistent for toCamelCaseKeys, especially in strongly-typed codebases.
  • Previously, TypeScript would infer incorrect key names for uppercase inputs (e.g. LASTlAST), which was confusing for consumers and could lead to subtle type errors.
  • By aligning the PascalToCamel type with how camelCase actually behaves, we make the API more predictable and safer to use, especially when dealing with API responses or legacy schemas that use uppercase keys.

Breaking Changes

  • No breaking changes are expected.
  • Runtime behavior of toCamelCaseKeys is unchanged.
  • Type-level behavior for uppercase keys is now more accurate:
    • Keys that were previously inferred as lAST are now correctly inferred as last.
  • This should only surface as a fix for consumers relying on proper key names in TypeScript, rather than a breaking change.

Copilot AI review requested due to automatic review settings November 26, 2025 13:06
@vercel
Copy link

vercel bot commented Nov 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
es-toolkit Ready Ready Preview Comment Nov 26, 2025 1:43pm

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a type inference issue in toCamelCaseKeys where uppercase keys (e.g., FIRST_NAME, LAST) were incorrectly typed at the type level (e.g., lAST instead of last), even though the runtime behavior was correct. The fix updates the PascalToCamel utility type to detect fully uppercase strings and convert them to fully lowercase, aligning TypeScript types with runtime behavior.

  • Updated the PascalToCamel type to handle uppercase keys by fully lowercasing them when all characters are uppercase
  • Added comprehensive test coverage for uppercase keys, PascalCase keys, and non-plain object handling
  • Updated documentation in all four supported languages (English, Korean, Japanese, Chinese) to clarify the behavior

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/object/toCamelCaseKeys.ts Updated PascalToCamel type to detect and handle uppercase keys by fully lowercasing them
src/object/toCamelCaseKeys.spec.ts Added three new test cases covering uppercase keys, PascalCase keys, and non-plain object handling with both runtime and type-level assertions
docs/reference/object/toCamelCaseKeys.md Added behavior documentation and example for uppercase and PascalCase key conversion
docs/ko/reference/object/toCamelCaseKeys.md Added Korean translation of behavior documentation and example
docs/ja/reference/object/toCamelCaseKeys.md Added Japanese translation of behavior documentation and example
docs/zh_hans/reference/object/toCamelCaseKeys.md Added Chinese (Simplified) translation of behavior documentation and example

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.97%. Comparing base (335011b) to head (d6491d0).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1538   +/-   ##
=======================================
  Coverage   99.97%   99.97%           
=======================================
  Files         474      474           
  Lines        4492     4493    +1     
  Branches     1313     1313           
=======================================
+ Hits         4491     4492    +1     
  Misses          1        1           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

toCamelCaseKeys has wrong type for single word keys in screaming snake case

2 participants