Skip to content

change-case/keys fails on Date objects #356

@ben-eb

Description

@ben-eb

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:

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

if (depth === 0 || !isObject(object)) return object;
- e.g:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions