`String.prototype.toCamelCase()` and others

Converting strings to other cases (including "camelCase", "PascalCase", "snake_case", etc.) is a fairly common task, – yet I haven't found any case-related proposals, neither in tc39/proposals GitHub repo, nor here (probably because there are countless npm libraries to do this conversion?).

So, basically, the proposal is trivial: for some cases (to be discussed), adding case-related methods to primitive strings and string instances, – I can think of several of those (the identifiers are also not set in stone):

const string = "hello world";

string.toCamelCase(); // "helloWorld"
string.toPascalCase(); // "HelloWorld"
string.toKebabCase(); // "hello-world"
string.toSnakeCase(); // "hello_world"
string.toConstantCase(); // "HELLO_WORLD"
string.toTitleCase(); // "Hello World"

Or (to avoid using arbitrary namings, such as "kebab" or "snake") this can be a single function, a-la Intl API, – but to me, this seems a bit over the top. If such a function is okay though, putting it statically on the String constructor might be a good choice too:

String.prototype.toCase(params);
String.toCase(string[, params]);
const string = "what a lovely day";

string.toCase();
// "what a lovely day"

string.toCase({ match: "n + 1", separator: "", pattern: "Aa*" }); // camelCase
// "whatALovelyDay"

string.toCase({ match: "n", separator: "_", pattern: "A*"}); // CONSTANT_CASE
// "WHAT_A_LOVELY_DAY"

string.toCase({ match: "n", separator: " ", pattern: "A*" }); // Title Case
// "What A Lovely Day"

string.toCase({ match: "n", separator: " ", pattern: "(Aa)*" });
// "WhAt A LoVeLy DaY"

string.toCase(
  { match: "1 - n", separator: "@", pattern: "a*" }, // first and second words
  { match: "n + 2", separator: "-", pattern: "A*" }, // third and subsequent words
);
// "what@a LOVELY-DAY"

I'm a bit uncertain about how this would work with punctuation, whitespace characters, and other non-word characters, but I guess this can be derived from how .toLowerCase() and .toUpperCase() work?

This seems like a niche issue. In what situation would you need to convert a string to camel-case, or any other case besides upper/lower? I've never come across a scenario where I needed to do that. And even if I did, it wouldn't be too hard to MacGyver a function from scratch to do just that.

this could be mildly useful when message-passing property-names between javascript (camelCase) and python / sql / filesystems (snake_case):

let dataJs = {
    responseText: "hello world",
    statusCode: 200
};

// convert property names from camelCase -> snake_case
// for message-passing compatibility between js <-> python api-endpoints
let dataPython = {};
Object.entries(dataJs).forEach(function ([
    key, val
]) {
    dataPython[key.toSnakeCase()] = val;
});
// dataPython = {"response_text": "hello world", "status_code": 200}

await fetch("https://python_api_server.com/api1", {
    body: JSON.stringify(dataPython)
});

Or just within the web platform:

  • translating between CSS property names (kebab-cased, like flex-grow) to the js version of them on the style object (camel-cased, like flexGrow)
  • translating between HTML data-* attribute names (kebab-cased, like data-foo-bar) and the properties on the dataset object (camel-cased, like el.dataset.fooBar)
2 Likes

Wouldn’t it be easier and more greppable/debuggable for the web to add aliases under the proper casing?

1 Like

To me, this question pops up pretty often during:

  • CI/CD pipeline configurations (e.g., when creating a feature environment based on the name of the feature branch);
  • cloud config (e.g., when creating an ID of an AWS lambda based on the name of a function).

Could you add an example?

The example is in what I'm replying to:

translating between HTML data-* attribute names (kebab-cased, like data-foo-bar) and the properties on the dataset object (camel-cased, like el.dataset.fooBar)

In other words, why not a el.dataset['foo-bar'] getter/setter alongside the fooBar one?

1 Like

I'm extremely in favor of this, at least from the context of CSS, but of course further discussion on that is obviously off-topic here.

Perhaps we need a capitalize method first – string[0].toUpperCase() + string.slice(1) is verbose.

.toTitleCase is Very Useful.
I think to create proposal like this, but here is :)

I find this:

String.prototype.toTitle = function () {
return this.toLowerCase().replace(/(^|\s)\S/g, function (char) {
return char.toUpperCase();
});
};

IMO this is required in all languages, with this we have opportunity to create good looking Title on submitting form

What would toTitle do with other languages? what about initialisms? "All About HTTP".toTitle() should not ever become "All About Http", for example.

1 Like

Ok, that's true, but on python running like my toTitle:

We can reformat this, for uppercase only first letter from every word

But, that wouldn't work well on strings like "hI tHeRe".

I think this sort of brings us back to "What is the concrete use case for this"? If the use case is "I have some text that might not be in the correct casing, but I want to put it in the title", perhaps a good question would be to ask why it's not in the correct casing. Properly casing a document title sounds like something that should be done by humans, not dumb algorithms. If, instead, the use case had something to do with translating the casing of JSON properties, to help facility communication with languages who follow different default casing standards, well, that provides a niche use-case for converting to camel-case and snake-case, but it doesn't help with the title-case scenario, so we still don't have a strong argument for it.