blakeembrey / blakeembrey/change-case
change-case/keys fails on Date objects
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 106
- PR merge metrics
- No merged PRs in 30d
Description
Hello 👋
Many thanks for your work on this project. I was hoping to use `change-case/keys` to automatically process database responses (in `snake_case` format) to `camelCase`.
Seeing as this is a global configuration option I wanted to use the `depth` option to work for either a single object returned from the database or an array of objects. However, when parsing a single object that contains a `Date` it looks like the `Date` is not passed through as a value. I have a minimal reproduction here:
```javascript
import { camelCase } from 'change-case/keys';
import { describe, it, expect } from 'vitest';
describe('change-case', () => {
it('should work with date objects', () => {
const originalInput = {date_time: new Date()};
const transformed = camelCase(originalInput, 2);
expect(() => transformed.dateTime.toISOString()).not.toThrowError();
});
});
```
This produces the following exception:
```
FAIL index.test.js > change-case > should work with date objects
AssertionError: expected [Function] to not throw an error but 'TypeError: Method Date.prototype.toIS…' was thrown
- Expected:
undefined
+ Received:
"TypeError: Method Date.prototype.toISOString called on incompatible receiver [object Object]"
❯ index.test.js:10:62
8| const transformed = camelCase(originalInput, 2);
9|
10| expect(() => transformed.dateTime.toISOString()).not.toThr…
| ^
11| })
12| })
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
```
I got this output from doing `console.log` on both objects:
```
{ date_time: 2025-01-31T12:45:08.814Z }
{ dateTime: Date {} }
```
I would imagine an easy fix would be to ignore `Date` in https://github.com/blakeembrey/change-case/blob/38e6b4f9115cf93b18ca9b1b4a620a32751499cb/packages/change-case/src/keys.ts#L16 - e.g:
```javascript
if (depth === 0 || !isObject(object) || object instanceof Date) return object;
```
However it might be nicer to check if the object is a "plain object" which should cover more cases - for example https://www.npmjs.com/package/is-plain-object
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with packages/change-case/src/keys.ts at the referenced recursion guard and run the provided Vitest reproduction for a Date-valued property. Check how Date objects are handled when depth is 2, then add or update a focused regression test. Done means the transformed date remains usable with toISOString() while existing key conversion behavior still passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100