Releases: gustavoguichard/string-ts
v2.2.0
What's Changed
Adds a replaceKeys
method to shallowly transform the keys of an object with the replace
method:
import { replaceKeys } from 'string-ts'
const data = {
helloWorld: {
fooBar: 'baz',
},
} as const
const result = replaceKeys(data, 'o', 'a')
// ^ { 'hellaWorld': { 'fooBar': 'baz' } }
PRs
- chore(deps-dev): bump @vitest/coverage-v8 from 1.5.2 to 1.6.0 by @dependabot in #202
- chore(deps-dev): bump tsup from 8.0.2 to 8.1.0 by @dependabot in #207
- chore(deps-dev): bump prettier from 3.2.5 to 3.3.2 by @dependabot in #211
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 7.7.1 to 7.13.1 by @dependabot in #212
- replaceKeys method by @gustavoguichard in #213
Full Changelog: v2.1.1...v2.2.0
v2.1.1
What's Changed
- fix: Expose deepTransformKeys by @gustavoguichard in #197
- chore: Update deps by @gustavoguichard in #199
Full Changelog: v2.0.0...v2.1.1
v2.1.0
Release notes
This release introduces a bunch of package updates and an important fix from @jly36963 to solve #181 and improve the library when working with interpolated strings or string unions. E.g:
startsWith(`abc${string}`, 'abc') // true
What's Changed
-
fix: handle template literals in startsWith by @jly36963 in #182
-
chore(deps-dev): bump @vitest/coverage-v8 from 1.0.4 to 1.1.0 by @dependabot in #139
-
chore(deps-dev): bump vitest from 1.0.4 to 1.1.0 by @dependabot in #140
-
chore: Better test types error messages by @gustavoguichard in #138
-
chore(deps): bump styfle/cancel-workflow-action from 0.12.0 to 0.12.1 by @dependabot in #163
-
chore(deps): bump codecov/codecov-action from 3 to 4 by @dependabot in #167
-
chore(deps-dev): bump prettier from 3.1.1 to 3.2.5 by @dependabot in #168
-
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.15.0 to 7.2.0 by @dependabot in #180
-
chore(deps-dev): bump @vitest/coverage-v8 from 1.1.0 to 1.4.0 by @dependabot in #183
-
chore(deps-dev): bump vitest from 1.1.0 to 1.4.0 by @dependabot in #184
-
chore(deps-dev): bump tsup from 8.0.1 to 8.0.2 by @dependabot in #171
Full Changelog: v2.0.0...v2.1.0
v2.0.0
Breaking Changes (not so much)
Now we will drop apostrophes in the casing transformation functions like so:
// string-ts@1.x.x
const result = camelCase(`I can't`)
// ^? "iCan'T"
// string-ts@2.x.x
const result = camelCase(`I can't`)
// ^? "iCant"
I personally consider this change a fix instead of a breaking change but we decided to cut a major release to avoid messing up with current expectations.
Improvements
Other PRs
- chore(deps-dev): bump prettier from 3.0.3 to 3.1.0 by @dependabot in #112
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.10.0 to 6.11.0 by @dependabot in #113
- chore(deps-dev): bump tsup from 7.2.0 to 8.0.1 by @dependabot in #119
- chore(deps-dev): bump typescript from 5.2.2 to 5.3.2 by @dependabot in #118
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.11.0 to 6.12.0 by @dependabot in #117
- chore(deps-dev): bump eslint from 8.53.0 to 8.54.0 by @dependabot in #116
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.12.0 to 6.13.1 by @dependabot in #121
- chore(deps-dev): bump eslint from 8.54.0 to 8.55.0 by @dependabot in #124
- chore(deps-dev): bump typescript from 5.3.2 to 5.3.3 by @dependabot in #127
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.13.1 to 6.13.2 by @dependabot in #126
- chore(deps-dev): bump @vitest/coverage-v8 from 0.34.6 to 1.0.2 by @dependabot in #128
- chore(deps-dev): bump prettier from 3.1.0 to 3.1.1 by @dependabot in #130
- chore(deps-dev): bump @vitest/coverage-v8 from 1.0.2 to 1.0.4 by @dependabot in #131
- chore(deps-dev): bump vitest from 1.0.2 to 1.0.4 by @dependabot in #132
- chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.13.2 to 6.15.0 by @dependabot in #137
- docs: add hverlin as a contributor for code by @allcontributors in #133
- chore(deps): bump actions/upload-artifact from 3 to 4 by @dependabot in #135
- chore(deps-dev): bump eslint from 8.55.0 to 8.56.0 by @dependabot in #136
New Contributors
Full Changelog: v1.3.3...v2.0.0
v1.3.3
What's Changed
The results of string functions should now be either deterministic (with string literals or unions of string literals) or fallback to standard types (for string interpolations or anything broader than that), eg:
type A = Slice<'foo', 0, 2> // 'fo'
type B = Slice<'foo' | 'bar', 0, 2> // 'fo' | 'ba'
type C = Slice<`foo${string}`, 0, 2> // string
type D = Slice<'foo', 0, number> // string
Kudos to @jly36963 for taking that challenge π
Pull requests
- chore: Move casing functions to casing folder and reorganize exports by @gustavoguichard in #95
- chore: Update README with Michigan TS interview by @gustavoguichard in #102
- docs: add banner to README by @agreea in #104
- fix: handle non-literal strings by @jly36963 in #105
- fix: better literal differentiation by @jly36963 in #107
New Contributors
Full Changelog: v1.3.2...v1.3.3
v1.3.2
What's Changed
- fix: re-export trim by @jly36963 in #82
- ci: add dependabot config by @p9f in #84
- ci: test output against previous version of typescript by @p9f in #83
- chore(deps-dev): bump eslint from 8.43.0 to 8.51.0 by @dependabot in #85
- chore(deps): bump actions/setup-node from 2 to 3 by @dependabot in #86
- chore(deps): bump actions/checkout from 3 to 4 by @dependabot in #88
- chore(deps-dev): bump prettier from 2.8.8 to 3.0.3 by @dependabot in #89
- chore(deps): bump styfle/cancel-workflow-action from 0.9.1 to 0.12.0 by @dependabot in #87
- chore(deps-dev): bump vitest from 0.32.2 to 0.34.6 by @dependabot in #91
- chore(deps-dev): bump tsup from 7.0.0 to 7.2.0 by @dependabot in #90
- chore(deps-dev): bump typescript from 5.1.6 to 5.2.2 by @dependabot in #92
New Contributors
- @dependabot made their first contribution in #85
Full Changelog: v1.3.0...v1.3.1
v1.3.0 - Organization, tree-shaking, normalization of functions names π³
What's changed
π Tree-shaking
This release brings a lot of internal architecture changes to make tree-shakingΒ as easy as possible for the bundlers.
With efforts from all the core contributors we were able to optimize the output of the package and re-organize the whole project to achieve that.
π‘οΈ 100% coverage
Now every line of string-ts
is covered with tests... and we mean type tests too!
π New methods
3 new methods were added:
π reverse
You can now reverse strings at both runtime and type-level. by @mjuksel
π¨βπ¦ upperCase
and lowerCase
Attention, these new methods are different than the native toLowerCase
and toUpperCase
as the existing ones (which already exist in this library) will only change the case of letters in a string and the new methods work similar to the other casing functions, such as camelCase
which will strip separators, split words and join them. So, think of lowerCase
as toLowerCase(delimiterCase("Hello-World...", ' ')) => "hello world"
.
In fact that is the exact implementation of the new lowerCase
at both runtime and type-level.
We are not adding the type utilities for these 2 new methods as they would cause a lot of confusion with the default Lowercase
and Uppercase
from TS. It is easy to build that type utility though:
import { type DelimiterCase } from "string-ts"
type MyLC<T extends string> = Lowercase<DelimiterCase<T, " ">>
type MyUC<T extends string> = Uppercase<DelimiterCase<T, " ">>
π΄πΌ Deprecations: Renaming and deprecating old casing utilities
As you could see in the section above, there's a difference in functionality between the native String.prototype.toLowerCase
(which maps to our toLowerCase
) and our own lowerCase
method. That is because most of the casing utilities will rely on the words
function splitting the words of a string, removing the separators and joining the characters in some fashion.
For that reason we decided to rename that second group by removing the to
prefix from those functions. We also deprecated the methods with old names so you want to rename those methods in your project to be prepared for string-ts@v2
:
// Prior to string-ts v1.3
import { toCamelCase, toDelimiterCase, toLowerCase } from 'string-ts'
const data = "Hello-World..."
const a = toCamelCase(data) // "helloWorld"
const b = toLowerCase(data) // "hello-world..."
const c = toDelimiterCase(data, '@') // "Hello@World"
const d = toLowerCase(toDelimiterCase(data, ' ')) // "hello world"
// From string-ts v1.3+
import { camelCase, delimiterCase, toLowerCase, lowerCase } from 'string-ts'
const data = "Hello-World..."
const a = camelCase(data) // "helloWorld"
const b = toLowerCase(data) // "hello-world..."
const c = delimiterCase(data, '@') // "Hello@World"
const d = lowerCase(data, ' ') // "hello world"
β¬οΈ PRs
- test: internals by @jly36963 in #50
- feat: add lowerCase and upperCase by @jly36963 in #47
- README update by @p9f in #53
- ci: compute code coverage in the CI by @p9f in #57
- chore: Adds contributors to the README by @gustavoguichard in #58
- doc: Update README.md by @p9f in #73
- feat: tree shake by @jly36963 in #52
- refactor: split files by @jly36963 in #56
- test: Improve coverage by @gustavoguichard in #75
- feat: Rename casing functions and deprecate old ones by @gustavoguichard in #76
- test: math by @jly36963 in #77
- feat: add a reverse method by @mjuksel in #74
New Contributors
Full Changelog: v1.2.0...v1.3.0
v1.2.0 - A bunch of other native string methods π
New features π
More methods: as we approach 800βοΈ (!!!) we are actively developing strongly-typed counterparts of native string functions.
This versions adds padStart
, padEnd
, includes
, startsWith
, endsWith
, and our own truncate
method.
Is there any method you'd like to see added to this library? Check the section below.
Roadmap πΊοΈ
We setup a list in our roadmap and that list is close to completion. Now there are other methods we might implement or not, so make sure you join the discussion if you want to see some of the β methods implemented!
Fixes π
- The
replace
now will accept a Regex but if you do it, the resulting type is gonna be loosened tostring
as TS doesn't do Regex yet. - The casing methods, such as
toCamelCase
,toDelimiterCase
, will strip out more separators. Even though it is breaking we consider it a bugfix astoCamelCase('hello [world]')
would previously result in"hello[World]"
and now it will be"helloWorld"
- The
slice
method is not a partial implementation anymore! Now we support the whole native API so you can send positive and negative indexes to both startIndex and endIndex parameters.
PR list π
- fix: Fix
slice
negative start and end indexes by @gustavoguichard in #28 - feat: add
startsWith
andendsWith
by @jly36963 in #27 - feat: Add strongly-typed
repeat
alternative by @gustavoguichard in #30 - feat: add
padStart
andpadEnd
methods by @gustavoguichard in #31 - chore: Update README.md to include supported TS versions by @gustavoguichard in #38
- feat: add
includes
by @jly36963 in #39 - refactor:
replace
with regex by @jly36963 in #42 - fix!: update separators by @jly36963 in #40
- feat: add
truncate
function by @p9f in #41 - docs: section headers by @jly36963 in #43
- chore: Code organization by @gustavoguichard in #45
New contributor π«Ά
@p9f had already contributed to the library but now he is an official contributor.
Full Changelog: v1.1.0...v1.2.0
v1.1.0 - More strongly-typed string methods π
What's Changed
This version adds a few more strongly-typed alternatives to the native string methods and by doing so we were able to simplify a lot of the internal methods' implementations.
With a lot of low level properly-typed utilities we can keep both type and runtime implementations in sync, like in this example:
// OLD Implementation
type CamelCase<T extends string> = T extends unknown
? PascalCase<T> extends `${infer first}${infer rest}`
? `${Lowercase<first>}${rest}`
: T
: never
function toCamelCase<T extends string>(str: T) {
const res = toPascalCase(str)
return (res.slice(0, 1).toLowerCase() + res.slice(1)) as CamelCase<T> // we needed to cast this type
}
// === πͺ ===
// NEW Implementation
type CamelCase<T extends string> = Uncapitalize<PascalCase<T>>
function toCamelCase<T extends string>(str: T): CamelCase<T> {
return uncapitalize(toPascalCase(str)) // type-checks without type casting
}
These changes aim to achieve the goal of this library which is the perfect synchrony between type-level and runtime string functions β€οΈ.
Support for older JS runtimes
We are now also able to run replaceAll
in older browsers that don't yet support it with a very simple polyfill .
Pull requests
- feat:
uncapitalize
,lengh
, andslice
methods by @gustavoguichard in #24 - feat:
concat
method by @jly36963 in #25 - feat: polyfill for
replaceAll
by @gustavoguichard in #26
Full Changelog: v1.0.0...v1.1.0
v1.0.0 π
string-ts
is trending!
This library got a lot of traffic (+570βοΈ and counting) after @mattpocock 's tweet about it yesterday!
That was the motivation I needed to fix some issues, add some methods, improve the docs, and so on.
The repo also got new contributors with new reported issues and new PR's.
It is now also been actively used in the development of 2 frameworks (AFAIK).
Thank you to all! I'm thrilled about the recognition and I hope you guys are able to make the best out of your literal types!
What's Changed
- Removed unnecessary
as const
by @mattpocock in #11 - Update package.json repository field by @iamandrewluca in #12
- Improve inference of
join
method by @mattpocock in #18 - Add a
charAt
method by @gustavoguichard in #17 - docs: further explanation by @jly36963 in #21
- feat: add shallow key casing transformation functions by @p9f in #16
- fix: Fixes a bug where
split(str, '')
- by empty string - would add an extra empty char to the resulting tuple by @gustavoguichard in #22
New Contributors
What makes me even more happy about the recent success of this library is to have received awesome new contributors to it!
- @jly36963 π§ became an official contributor to the project β€οΈ
- @mattpocock π§πΏββοΈ made their first contribution in #11
- @iamandrewluca π¦ made their first contribution in #12
- @p9f π made their first contribution in #16
Full Changelog: v0.5.1...v1.0.0