Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(capitalize,toLowerCase,toUpperCase,uncapitalize): add capitalize, toLowerCase, toUpperCase and uncapitalize #525

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

lensbart
Copy link
Contributor

@lensbart lensbart commented Feb 18, 2024

Fixes #509

  • Typedoc added for new methods and updated for changed
  • Tests added for new methods and updated for changed
  • New methods added to src/index.ts
  • New methods added to mapping.md

Copy link

codesandbox-ci bot commented Feb 18, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit f71f97e:

Sandbox Source
remeda-example-vanilla Configuration

Copy link

codecov bot commented Feb 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.52%. Comparing base (96a4e82) to head (f71f97e).
Report is 49 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #525      +/-   ##
==========================================
+ Coverage   98.41%   98.52%   +0.10%     
==========================================
  Files         127      139      +12     
  Lines        7954     9132    +1178     
  Branches      724      779      +55     
==========================================
+ Hits         7828     8997    +1169     
- Misses        123      132       +9     
  Partials        3        3              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lensbart
Copy link
Contributor Author

lensbart commented Mar 4, 2024

@eranhirsch any chance that this can get a review? This PR has conflicts now, due to other PR’s that have been opened and merged in the meantime.

@eranhirsch
Copy link
Collaborator

Hey, I'm sorry for the delays. The other PRs being merged are mine, and I'm sorry for the extra work they are incurring. I'm getting them done as quickly as possible to minimize these conflicts. The gist is that I'm reinforcing typescript and eslint (and prettier) in the project so that PRs get better feedback quicker, requiring fewer cycles and allowing me to review more PRs faster. Unfortunately, this delays reviewing the current PRs.

By the end of this week, those changes should be done, and then a simple merge from master should bring your environment up to speed You can follow the lint fixes and suggestions if any issues are raised. If you haven't already, you can always run npx tsc, npm run lint and npx prettier . --write to make sure you are getting the right signals from the CI.

Copy link
Collaborator

@eranhirsch eranhirsch left a comment

Choose a reason for hiding this comment

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

Hey, I merged the index file for you, can you pull this PR locally, run:
npx prettier . --write to bring styling up-to-date, and run npm run lint and fix any issues (I think it's just adding return types).

Also, please add dataLast implementations for all functions so they could be used in mappers and pipes, e.g.

pipe(
  stringData,
  map(toLowerCase()),
  ...
);

@lensbart lensbart force-pushed the lensbart/string-functions branch 4 times, most recently from 134812f to 72e0e82 Compare March 9, 2024 22:53
@lensbart
Copy link
Contributor Author

lensbart commented Mar 9, 2024

I rebased, re-formatted and added return types.

Also, please add dataLast implementations for all functions so they could be used in mappers and pipes, e.g.

pipe(
  stringData,
  map(toLowerCase()),
  ...
);

Does this make sense? This PR introduces functions that take just 1 argument, so they could safely be used in mappers and pipes like so:

pipe(
  stringData,
  map(toLowerCase),
  ...
);

This is consistent with e.g. the isNil and type functions.

@lensbart lensbart requested a review from eranhirsch March 9, 2024 23:04
@eranhirsch
Copy link
Collaborator

We're moving away from 'headless' dataLast invocations for functions that don't take any parameters. They don't always work (like first), and that creates a confusing and inconsistent API where people might either add parenthesis to a headless function or not add parenthesis to a non-headless one and not get any meaningful errors to fix the issue.

See: #531

Unfortunately, we can't switch to a consistent format without breaking changes, so we are waiting to release Remeda V2 for this.

Copy link
Collaborator

@eranhirsch eranhirsch left a comment

Choose a reason for hiding this comment

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

Let's add native dataLast implementations

@@ -0,0 +1,14 @@
/**
* A function equivalent to TypeScript’s built-in `Capitalize` utility type.
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't need to mention "a function" because everything in Remeda is a function. Assuming people don't know Typescript's Capitalize util, it would be easier for people to get the full description for this function right here...

Suggestion (via chatgpt):

Converts the first character of a given string to uppercase while maintaining the rest of the string as is.

* @category String
* @strict
*/
export const capitalize = <T extends string>(string: T): Capitalize<T> =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

To prevent any accidental confusion, let's avoid calling the variable string as it's also the type name.

Suggested change
export const capitalize = <T extends string>(string: T): Capitalize<T> =>
export const capitalize = <T extends string>(str: T): Capitalize<T> =>

src/toLowerCase.test.ts Show resolved Hide resolved
@@ -0,0 +1,30 @@
/* eslint-disable no-useless-escape */
Copy link
Collaborator

Choose a reason for hiding this comment

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

put this above the line that needs it. If you need it for a block prefer wrapping that area with:

/* eslint-disable no-useless-escape */
...
...
...
/* eslint-enable no-useless-escape */

@Brian-Pob
Copy link

Apologies for my ignorance, but what is the purpose of implementing functions like toLoweCase and toUpperCase when they already exist in native JavaScript? The only difference I can see is how you call them:

R.toLowerCase("MyString");

"MyString".toLowerCase();

// alternatively
const mystr = "MyString";
mystr.toLowerCase();

Thanks.

@lensbart
Copy link
Contributor Author

@Brian-Pob

If some variable is typed as a string literal, the result of toLowerCase(variable) will be typed as the corresponding string literal, whereas variable.toLowerCase() will be typed as string.

@Brian-Pob
Copy link

@Brian-Pob

If some variable is typed as a string literal, the result of toLowerCase(variable) will be typed as the corresponding string literal, whereas variable.toLowerCase() will be typed as string.

I see. I get it now after reading your explanation and looking at the implementation. Thanks.

@eranhirsch
Copy link
Collaborator

eranhirsch commented Mar 27, 2024

Also you get the added value of being able to use the dataLast version in pipes and mappers so you can write:

R.map(data, R.toLowerCase());

instead of:

data.map((tempName) => tempName.toLowerCase());

which itself becomes more useful once you start using pipes:

const result = R.pipe(
  someArrayOfNonStringData,
  R.filter(...),
  R.map(...a mapper that returns a string...),
  R.take(5),
  R.join("-"),
  R.toLowerCase(),
);

In the example above you will only run the filter and mapper on the first 5 objects that fulfil the mapper, you will only join 5 items, and then run lowercase just once on the output object.

@Brodzko
Copy link
Contributor

Brodzko commented Apr 2, 2024

I'm also not sure what's the utility of uncapitalize. Are there many use-cases where you only want the first letter to lower-case?

@lensbart
Copy link
Contributor Author

lensbart commented Apr 2, 2024

@Brodzko uncapitalize can be used to convert PascalCase to camelCase. IMO the utility of uncapitalize is like the utility of Uncapitalize. Since this utility type is part of the TypeScript API, in my view it makes sense to include the corresponding function in a TypeScript-specific utility library.

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.

A couple of suggestions
4 participants