GithubHelp home page GithubHelp logo

camelcase-keys's Introduction

camelcase-keys

Convert object keys to camel case using camelcase

Install

npm install camelcase-keys

Usage

import camelcaseKeys from 'camelcase-keys';

// Convert an object
camelcaseKeys({'foo-bar': true});
//=> {fooBar: true}

// Convert an array of objects
camelcaseKeys([{'foo-bar': true}, {'bar-foo': false}]);
//=> [{fooBar: true}, {barFoo: false}]
import {parseArgs} from 'node:util';
import camelcaseKeys from 'camelcase-keys';

const commandLineArguments = parseArgs();
//=> {_: [], 'foo-bar': true}

camelcaseKeys(commandLineArguments);
//=> {_: [], fooBar: true}

API

camelcaseKeys(input, options?)

input

Type: Record<string, unknown> | ReadonlyArray<Record<string, unknown>>

A plain object or array of plain objects to camel-case.

options

Type: object

exclude

Type: Array<string | RegExp>
Default: []

Exclude keys from being camel-cased.

deep

Type: boolean
Default: false

Recurse nested objects and objects in arrays.

import camelcaseKeys from 'camelcase-keys';

const object = {
	'foo-bar': true,
	nested: {
		unicorn_rainbow: true
	}
};

camelcaseKeys(object, {deep: true});
//=> {fooBar: true, nested: {unicornRainbow: true}}

camelcaseKeys(object, {deep: false});
//=> {fooBar: true, nested: {unicorn_rainbow: true}}
pascalCase

Type: boolean
Default: false

Uppercase the first character: bye-bye โ†’ ByeBye

import camelcaseKeys from 'camelcase-keys';

camelcaseKeys({'foo-bar': true}, {pascalCase: true});
//=> {FooBar: true}

camelcaseKeys({'foo-bar': true}, {pascalCase: false});
//=> {fooBar: true}
preserveConsecutiveUppercase

Type: boolean
Default: false

Preserve consecutive uppercase characters: foo-BAR โ†’ FooBAR

import camelcaseKeys from 'camelcase-keys';

camelcaseKeys({'foo-BAR': true}, {preserveConsecutiveUppercase: true});
//=> {fooBAR: true}

camelcaseKeys({'foo-BAR': true}, {preserveConsecutiveUppercase: false});
//=> {fooBar: true}
stopPaths

Type: string[]
Default: []

Exclude children at the given object paths in dot-notation from being camel-cased.

For example, with an object like {a: {b: '๐Ÿฆ„'}}, the object path to reach the unicorn is 'a.b'.

import camelcaseKeys from 'camelcase-keys';

const object = {
	a_b: 1,
	a_c: {
		c_d: 1,
		c_e: {
			e_f: 1
		}
	}
};

camelcaseKeys(object, {
	deep: true,
	stopPaths: [
		'a_c.c_e'
	]
}),
/*
{
	aB: 1,
	aC: {
		cD: 1,
		cE: {
			e_f: 1
		}
	}
}
*/

Related

camelcase-keys's People

Contributors

bendingbender avatar coreyfarrell avatar dsblv avatar duynguyenhoang avatar egoist avatar emmyakin avatar g-plane avatar haakondr avatar jhnns avatar jonshort avatar jwthanh avatar mahovich avatar masa-shin avatar mattiloh avatar nano72mkn avatar niktekusho avatar rdsedmundo avatar seanghay avatar simonradier avatar sindresorhus avatar stroncium avatar timwis avatar yutak23 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

camelcase-keys's Issues

Add ES5 version to NPM release

Hey @sindresorhus, thanks for this super-helpful utility. I'm curious if you can provide an ES5 version of camelcase-keys (and camelcase), that would reduce the need for us to transpile this in our build.

I'd be glad to submit a PR, if this is something you're open to.

Best,
Sam

camelcase-keys & snakecases-keys inconsistent default behaviour

@sindresorhus @bendrucker

Both of your packages communicate a similar api, but you don't use the same defaults. The deep option for camelcase-keys is false where it is true for snakecase-keys. I would suggest standardising the default to prevent unsuspected behaviour as I experienced first hand.

I believe defaulting the deep option to true aligns with most preferences.

camelcaseKeys return key types on camelcase without exclude prop.

I have class with types for my object and I using convert to camel case like that with exclude keys:

camelcaseKeys(data, { exclude: ['iso_639_1', 'iso_3166_1'], deep: true });

Data after formatting camelcaseKeys is normal, but ts see like iso keys on camel cases to iso6391.
image

export declare class MovieDetails {
  id: number;
  budget: number;
  imdb_id: string | null;
  images: Images
  genres: Genre[];
  spoken_languages: Language[];
  overview: string | null;
  poster_path: string | null;
  production_companies: Company[];
  production_countries: Country[];
  revenue: number;
  runtime: number;
  status: string;
  tagline: string;
  belongs_to_collection: Collection | null;
  title: string;
  homepage: string | null;
  original_title: string;
  adult: boolean;
  release_date: string;
  keywords: {
    keywords: Keyword[];
  };

  credits: MovieCredits;
  lists: ListData<MovieListItem>;
  videos: Videos;
  recommendations: ListData<MoviesListItem>;
  backdrop_path: string;
  original_language: string;
  popularity: number;
  vote_count: number;
  video: boolean;

  vote_average: number;
}

export declare class Language {
  iso_639_1: string;
  name: string;
}

export declare class Images {
  backdrops: Image[];
  posters: Image[];
  logos: Image[];
}

export declare class Image {
  aspect_ratio: number;
  file_path: string;
  height: number;
  iso_639_1: string | null;
  vote_average: number;
  vote_count: number;
  width: number;
}

and etc...

Maybe add some generic only for return type, not only one generic for input and return type?
image

Pitfall using Turkish locale

Hi ๐Ÿ‘‹

thanks for this module โ€“ and all the other modules ๐Ÿ™

I recently ran into a problem where my JSON objects were transformed into this:

            "customersฤฐd": 619336, // <-- notice the different capital i character
            "projectsฤฐd": 631365,
            "usersฤฐd": 62488,

Unfortunately, this didn't happen locally and during testing, it only happened in production in case the user was using the Turkish locale. There's already an issue in the camelcase repo describing the problem.

I kind of understand that toLocaleUpperCase() is the default for the camelcase package since the context of the "to camelcase" transformation is not clear.

However, I think that camelcase-keys should use the locale-independent toUpperCase(). This is because I'm assuming that most people are using this module in a context where they want to transform API responses to camelCase in a predictable way. Using toLocaleUpperCase() poses the risk that API responses are transformed into a different shape on runtime. Also toLocaleUpperCase("en") doesn't really help since the locale might be unavailable and the host might fall back to the default locale.

I think this issue could be solved like this:

  • Add an option to camelcase to use the locale-independent toUpperCase()
  • Use that option as default in camelcase-keys

What do you think? ๐Ÿ˜€ I'd be willing to help out if that's ok.

regex index problem

I would like to exclude key with start of "_"
camelcaseKeys(object, { deep: true, exclude: [/^\_/ig] });
However, I found that some of keys has not follow that rule because the lastIndex of the regex has changed when it test the keys one by one and make it fail to test.
I have rewrite the "has" function to solve this problemfunction has(array, key) { return array.some(x => { if (typeof x === 'string') return x === key; else { x.lastIndex = 0; return x.test(key) } }); }
I am wondering if there has any better solution and if it can fix it in next version. thanks

Wrong result with log4j word to camel case?

I have different words with log4j. The one of example is uses_log4j.

var camelcaseKeys = require("camelcase-keys")
camelcaseKeys({'uses_log4j': true}); 
//=> usesLog4J

The result of that word should be usesLog4j ? why is making capital letter after a number?

Use recuse version of map-obj ?

Either via an option -- or -- by default (I can't imagine too many use cases where you wouldn't want this) use map-obj-recurse instead of map-obj so the whole object graph gets converted??

If interested I can certainly do a PR for this ..

Option 'deep' does nothing in 6.2.1

Hi,
in release 6.2.1 the Option 'deep' does nothing.

camelcaseKeys({a_b: {c_d: 1}}, {deep:true})
//=> {aB: {c_d: 1}}

I tested 6.1.2 and in that release everything was fine.

Options {deep: true} seem run incorrect

Issuehunt badges

screenshot from 2019-02-25 13-23-10

camelcaseKeys({'foo-bar': true, nested: {unicorn_rainbow: true}}, {deep: true});
expect
//=> {fooBar: true, nested: {unicornRainbow: true}}
actual
//=> {fooBar: true, nested: {unicorn_rainbow: true}

IssueHunt Summary

Backers (Total: $0.00)

Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Weird behaviour with array of objects as input

camelcaseKeys([{'foo-bar': true}], {deep:true})

gives

{
    0: {
        fooBar: true
    }
}

I was expecting

[
    {
        fooBar: true
    }
]

Since

camelcaseKeys({'test': [{'foo-bar': [{'foo-baz': true}]}]}, {deep:true});

Gives

{
    test: [
        {
            fooBar: [{ fooBaz }]
        }
    ]
}

Error using pascalCase option with different values

Error in the result when using the pascalCase option with different values.

For example:

console.log(camelcaseKeys({foo_bar: true}));
//=> { fooBar: true }
console.log(camelcaseKeys({foo_bar: true}, {pascalCase: true}));
//=> { fooBar: true }

or so

console.log(camelcaseKeys({foo_bar: true}, {pascalCase: true}));
//=> { FooBar: true }
console.log(camelcaseKeys({foo_bar: true}));
//=> { FooBar: true }

It should be:

console.log(camelcaseKeys({foo_bar: true}));
//=> { fooBar: true }
console.log(camelcaseKeys({foo_bar: true}, {pascalCase: true}));
//=> { FooBar: true }

I created kebabcase-keys based on a fork of this package

Hi Sindre! Thanks for sharing another neat and useful package with the world ๐Ÿ™
I needed a conversion from camelCase to kebab-case, so I forked this repo and published a package with the same API for kebab-case conversion: https://github.com/mattiloh/kebabcase-keys

I only changed the case-conversion, the rest is untouched. I'm not sure how to adjust the license file in this case, so I just didn't touch it. Please let me know, if I should change it or adjust the way I give credit to your work.

Adding camelcase-keys to Ember.js app breaks Internet Explorer 11

We have an Ember 2.16 application, that loads correctly on Internet Explorer 11. When we add camelcase-keys:

+++ b/frontend/package.json
@@ -29,6 +29,7 @@
     "breakpoint-sass": "^2.7.1",
     "broccoli-asset-rev": "^2.4.5",
     "broccoli-babel-transpiler": "^5.7.2",
+    "camelcase-keys": "^4.2.0",

... then the application fails to load, with the following error:

SCRIPT5009: 'define' is undefined

... but only on IE11. All other browsers we test against work fine.

v6 breaks on edge

Since the upgrade from v5.2=>6 this package has been broken on edge due to a lack of support for the object spread operator.

v5.2.0...v6.0.0#diff-168726dbe96b3ce427e7fedce31bb0bc

camelcase-keys/index.js

Lines 10 to 13 in 807dd95

options = {
deep: false,
...options
};

According to MDN, this is not supported at al by Edge
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Browser_compatibility

As far as I can tell, this makes version 6 unsafe for web.

Would it be possible to go back to using Object.assign or to publish something that is Babelized for all browser? IMO it would be onerous to expect implementers to run their node_modules through Babel.

Inconsistent behavior with Arrays

const camelcaseKeys = require('camelcase-keys');

At top level, array members are turned into array elements.

(a = [{test_one: 1}]).test_two = {}; a;
// [ { test_one: 1 }, test_two: {} ]
camelcaseKeys(a);
// [ { testOne: 1 }, {} ]

At lower levels, array members are lost.

(o = {deep: [{test_one: 1}]}).deep.test_two = 1; o;
// { deep: [ { test_one: 1 }, test_two: 1 ] }
camelcaseKeys(o, {deep: true});
// { deep: [ { testOne: 1 } ] } }

I realize this is bad practice.
However, that this library mangles them and, in particular, inconsistently is I think problematic.

Proposed solution

map-obj already has the ability to handle Arrays.
Simply remove the extra function at module.exports and export camelCaseConvert directly.

Side note

Doesn't map-obj already have a caching mechanism?
It seems a little redundant to me to have a caching layer in this package.
Maybe I'm missing something?

TypeError: Invalid value used as weak map key

No idea why, but I was getting this error. Do you know if I'm using some sort of wrong value as a key in object?

ERROR RETURNED TO CLIENT: TypeError: Invalid value used as weak map key
at WeakMap.set (native)
at mapObj (/home/jperelli/celerative/wysh/WYSHAPI/node_modules/map-obj/index.js:23:7)
at module.exports (/home/jperelli/celerative/wysh/WYSHAPI/node_modules/camelcase-keys/index.js:16:9)
at /home/jperelli/celerative/wysh/WYSHAPI/.webpack/service/app/requests/list.js:560:50
at Array.map (native)
at /home/jperelli/celerative/wysh/WYSHAPI/.webpack/service/app/requests/list.js:555:21
at process._tickDomainCallback (internal/process/next_tick.js:129:7)

Not Camelcasing Nested Objects/Arrays

I can't seem to get the { deep: true } options obj to work. Trying the example in the README:

camelcaseKeys({'foo-bar': true, nested: {unicorn_rainbow: true}}, {deep: true});
// returns { fooBar: true, nested: { unicorn_rainbow: true } }

Any idea why this isn't working as expected?

Any help is appreciated. Thanks in advance!

Feature request: reverse transformation

I'd prefer to use camelcase-keys as a one-stop library for converting a snake case API result into camelcase for client side JS, and then converting client side JS camelcase back into snake case for sending back to the same API.

Other libraries like decamelize-keys and snakecase-keys exist, but from a library consumer's perspective it would be preferable to have symmetrical transformations in a single library.

Please consider adding this use case to the supported feature set.

decimal points in keys are stripped by camelcaseKeys

This wouldn't be my approach but I've inherited a codebase which uses floats as keys in some of the api responses. These get stripped out when using camelcaseKeys.

const camelcaseKeys = require('camelcase-keys');
camelcaseKeys({ 2.95: true }); // { 295: true }

ERROR in ./~/camelcase-keys/index.js

I've met a trouble when import camelcaseKeys:
image

This is my webpack.config.js file:

const path = require('path');
const sourcePath = path.join(__dirname, './app/assets');
const autoprefixer = require('autoprefixer');
const webpack = require("webpack");
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const NODE_ENV = 'development';
const rules = {
  js: {
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
      query: {
        plugins: [
          '@babel/plugin-proposal-class-properties',
          ['import', {'libraryName': 'antd', 'style': true}],
          ['module-resolver', { 'root': ["./"] }],
          'lodash'
        ],
        presets: [['@babel/preset-env', { modules: false, targets: { node: 4 } }], '@babel/preset-react']
      }
    }
  },
  json: {
    test: /\.json$/,
    loader: 'json-loader'
  },
  componentCss: {
    test: /\.css$/,
    loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
  },
  componentStyles: {
    test: /\.scss$/,
    use: ExtractTextPlugin.extract({
      fallback: 'style-loader',
      use: ['css-loader','postcss-loader','sass-loader']
    })
  },
  fonts: {
    test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
    loader: 'file-loader?name=fonts/[name].[ext]'
  },
  images: {
    test: /\.(png|jpe?g|gif|ico)$/,
    loader: "url-loader?name=/images/milan_version/[name].[ext]"
  },
  less: {
    test: /\.less$/,
    use: [{
      loader: 'style-loader',
    }, {
      loader: 'css-loader', // translates CSS into CommonJS
    }, {
      loader: 'less-loader', // compiles Less to CSS
      options: {
        javascriptEnabled: true
      }
    }]
  }
};
const config = module.exports = {};
config.resolve = {
  extensions: ['.js','.less', '.scss', '.json'],
  mainFields: ['module', 'browser', 'main'],
  modules: [
    path.resolve('.'),
    path.resolve('node_modules'),
    path.resolve('./app/assets/javascripts/react_code')
  ],
};
config.module = {
  rules: [
    rules.js,
    rules.json,
    rules.images,
    rules.componentCss,
    rules.componentStyles,
    rules.fonts,
    rules.less
  ], 
  noParse: /jquery|lodash/
};

When I use

import camelcaseKeys from 'camelcase-keys';

in js file then webpack raised above error message.
What am I missing? Can u help me to resolve it?
Thank you.

Possible to have stopPaths not be relative to the data root?

I love the stopPaths feature, however, in a structure that looks something like this:

{
  "foo": [
    {
      "bar": {
        "baz": {...}
      }
    }
  ] 
}

... where I want baz to remain uncamelized, it's kinda unusable, as far as I understand.

Would it be possible to do something like stopPaths: ['*.bar.baz']? Does that make sense?

Failed to minify the code from this file....

Hello!

My node version - 8.1.4
npm version - 5.3.0
yarn version - 0.27.5

react-scripts version 1.0.17

I'm using create-react-app, and works well, but when I call

yarn run build

I've got an error:

yarn run v0.27.5
$ react-scripts build
Creating an optimized production build...
Failed to compile.

Failed to minify the code from this file:

        ./node_modules/camelcase-keys/index.js:6

Read more here: http://bit.ly/2tRViJ9

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

There is the same error with camelcase, map-obj, and maybe somewhere else.

Error when import with webpack

Module parse failed: /home/anh/test/node_modules/camelcase-keys/index.js Unexpected token (12:2)
You may need an appropriate loader to handle this file type.
| 	options = {
| 		deep: false,
| 		...options
| 	};
| 

Does not camelize keys of nested objects

camelcaseKeys() works perfectly fine for a flat json object. However, the keys of nested json objects wont camelize.

ex: //works fine for
{
'foo-bar': true,
'foo bar2': true,
'foo_bar_foo': true,
}

ex 2: //Doesn't work for
{
'foo-bar': true,
'nested.foo':
{
'foo-bar': true,
'foo bar2': true,
'foo_bar_foo': true
}
}

//ex 2: Output
{ fooBar: true,
nestedFoo: { 'foo-bar': true, 'foo bar2': true, foo_bar_foo: true } }

Convert Object from Sequelize

I am trying to convert a object from Sequelize like this:

Users.findById(event.queryStringParameters.id, { include: [{ all: true }]}).then(function (acc) {
        if (acc != null) {
            //console.log(camelcaseKeys(acc));
            return cb(null, Api.response(camelcaseKeys(acc)));
        } else {
            return cb(null, Api.errors(200, "Nothing found"));
        }
    }).catch(function (err) {
        console.log(err);
        return cb(null, Api.errors(400, err['message']));
    });

And I get this error: Converting circular structure to JSON

Also tried: return cb(null, Api.response(camelcaseKeys(JSON.parse(acc))));
And another error occurs.

Allow paths to be excluded from transformation

Issuehunt badges

Allow certain paths to be excluded from transformation (excludePaths). This is necessary when certain subpaths of the structure hold pure data that are not part of the model. For example, one of the keys might hold key-value pair data, but that key-value pair data cannot be corrupted.

I'm imagining something like:

camelcaseKeys(raw, { deep: true, excludePaths: ['path.to.hash'] })

It would be the data inside this path, not the path itself, that would be excluded.


IssueHunt Summary

stroncium stroncium has been rewarded.

Backers (Total: $60.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

exclude regex

hi guys, is it possible to exclude a regex?

I know this is supported that it excludes the key 'foo'

camelcaseKeys(o, {exclude: ['foo']}))

But I was wondering if I could say all the keys that start with foo*

Thanks!

How to use with Typescript?

What's the recommended way to use this currently with Typescript as all the examples are broken for me in the latest vscode.

Typescript: 3.9.0-dev-20200408
VS Code: 1.44.0
Camelcase-keys: 6.2.2

import camelcaseKeys from 'camelcase-keys';

// Convert an object
camelcaseKeys({ 'foo-bar': true });
// (alias) camelcaseKeys<{
//     'foo-bar': boolean;
// }>(input: {
//     'foo-bar': boolean;
// }, options ?: camelcaseKeys.Options): {
//     'foo-bar': boolean;
// } (+1 overload)

// Convert an array of objects
camelcaseKeys([{ 'foo-bar': true }, { 'bar-foo': false }]);
// (alias) camelcaseKeys<({
//     'foo-bar': boolean;
//     'bar-foo'?: undefined;
// } | {
//     'bar-foo': boolean;
//     'foo-bar'?: undefined;
// })[]>(input: ({
//     'foo-bar': boolean;
//     'bar-foo'?: undefined;
// } | {
//     'bar-foo': boolean;
//     'foo-bar'?: undefined;
// })[], options ?: camelcaseKeys.Options): ({
//     ...;
// } | {
//     ...;
// })[](+1 overload)

camelcaseKeys({ 'foo-bar': true, nested: { unicorn_rainbow: true } }, { deep: true });
// (alias) camelcaseKeys<{
//     'foo-bar': boolean;
//     nested: {
//         unicorn_rainbow: boolean;
//     };
// }>(input: {
//     'foo-bar': boolean;
//     nested: {
//         unicorn_rainbow: boolean;
//     };
// }, options ?: camelcaseKeys.Options): {
//     'foo-bar': boolean;
//     nested: {
//         ...;
//     };
// } (+1 overload)

camelcaseKeys({ a_b: 1, a_c: { c_d: 1, c_e: { e_f: 1 } } }, { deep: true, stopPaths: ['a_c.c_e'] }),
// (alias) camelcaseKeys<{
//     a_b: number;
//     a_c: {
//         c_d: number;
//         c_e: {
//             e_f: number;
//         };
//     };
// }>(input: {
//     a_b: number;
//     a_c: {
//         c_d: number;
//         c_e: {
//             e_f: number;
//         };
//     };
// }, options?: camelcaseKeys.Options): {
//     a_b: number;
//     a_c: {
//         c_d: number;
//         c_e: {
//             ...;
//         };
//     };
// } (+1 overload)

// Convert object keys to pascal case
camelcaseKeys({ 'foo-bar': true, nested: { unicorn_rainbow: true } }, { deep: true, pascalCase: true });
// (alias) camelcaseKeys<{
//     'foo-bar': boolean;
//     nested: {
//         unicorn_rainbow: boolean;
//     };
// }>(input: {
//     'foo-bar': boolean;
//     nested: {
//         unicorn_rainbow: boolean;
//     };
// }, options ?: camelcaseKeys.Options): {
//     'foo-bar': boolean;
//     nested: {
//         ...;
//     };
// } (+1 overload)

No default export found in imported module "camelcase-keys"

Hi and thank you for your work on this. This might be more appropriate to ask over at eslint-plugin-import -- I am not sure yet.

camelcase-keys: 6.2.2
snakecase-keys: 3.2.0

eslint: 6.8.0
eslint-plugin-import: 2.20.1

typescript: 3.8.2
vs Code: 1.44.2

In my project, camelcaseKeys is imported and called successfully, but I get the below error when linting:

import camelcaseKeys from 'camelcase-keys' // <-- here
import { expect } from 'chai'
import snakecaseKeys from 'snakecase-keys'

describe('keys tests', () => {
  describe('camelcaseKeys', () => {
    it('changes keys to camelcase', () => {
      // eslint-disable-next-line @typescript-eslint/camelcase
      const result = camelcaseKeys({ snake_case: 'value' })
      expect(result).to.be.deep.equal({ snakeCase: 'value' }) // <-- passes
    })
  })

  describe('snakecaseKeys', () => {
    it('changes keys to snakecase', () => {
      const result = snakecaseKeys({ camelCase: 'value' })
      // eslint-disable-next-line @typescript-eslint/camelcase
      expect(result).to.be.deep.equal({ camel_case: 'value' }) // <-- passes
    })
  })
})

1:8 error No default export found in imported module "camelcase-keys" import/default

If it is useful, here is the tsconfig:

{
  "compilerOptions": {
    "alwaysStrict": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "*": ["@types/*.d.ts"]
    },
    "allowJs": true,
    "typeRoots": ["overrides", "node_modules/@types"]
  }
}

Strangely, I have no linting issue default importing from snakecase-keys, whose index file seems structurally the same to that of camelcase-keys.

Thank you for any guidance. I am pretty new to typescript so I may be missing something simple.

Pascalcase option doesnt work

I'm trying to convert camelCase to PascalCase, but this doesn't work for me.

camelcaseKeys({fooBar: true, nested: {unicorn_rainbow: true}}, {pascalCase: true});

returns:
{fooBar: true, nested: {unicorn_rainbow: true}}

Generic parameter type, breaking change

We are using camelcase-keys by passing in objects typed as interfaces, and the type check failed after upgrading to 6.0.2, related change #54, #50. Minimal example:

interface SomeObject {
	someProperty: string;
}

const someObj: SomeObject = {
	someProperty: "hello",
};

camelcaseKeys(someObj);

typescript then complains with the following:

  โœ–  37:14  No overload matches this call.
  Overload 1 of 2, (input: readonly { [key: string]: unknown; }[], options?: Options | undefined): readonly { [key: string]: unknown; }[], gave the following error.
    Argument of type SomeObject is not assignable to parameter of type readonly { [key: string]: unknown; }[].
      Type SomeObject is missing the following properties from type readonly { [key: string]: unknown; }[]: length, concat, join, slice, and 16 more.
  Overload 2 of 2, (input: { [key: string]: unknown; }, options?: Options | undefined): { [key: string]: unknown; }, gave the following error.
    Argument of type SomeObject is not assignable to parameter of type { [key: string]: unknown; }.
      Index signature is missing in type SomeObject.  

I did solve this by extending my interface with the following:

interface CamelCasable {
	[key: string]: unknown;
}

interface SomeObject extends CamelCasable {
	someProperty: string;
}

This way, my interface adheres to the required parameter type in the camelcaseKeys function. I do agree that this type check is correct. Problem is, I then have to add this to all the objects I pass in to camelcaseKeys in my project.

My question is then as follows:

  • is there an alternative to make the parameter type slightly less restrictive?

something like:

declare function camelcaseKeys<T>(
	input: T,
	options?: camelcaseKeys.Options,
): T;
  • Alternatively, should I reconsider my approach of using interfaces as types?

I can make a PR with code example changes, but I thought I'd start the discussion first. Not sure if this is really a problem, or me doing typescript the wrong way.

build failed

$ react-scripts build
Creating an optimized production build...
Failed to compile.

static/js/main.472219b2.js from UglifyJs
Invalid assignment [./~/camelcase-keys/index.js:6,0][static/js/main.472219b2.js:18310,23]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.