Transforming a string to upper case is a breeze with the handy Uppercase<T>
utility type.
type UppercaseString<STR extends string> = {
original: STR,
upperCased: Uppercase<STR>
}
const myString: UppercaseString<'hello_world'> = {
original: 'hello_world',
upperCased: 'HELLO_WORLD',
} as const
See playground
Now, let's dive into transforming a string to camel case, which is a bit more complex.
Here's one approach to achieving this.
type CamelCase<STR extends string> =
STR extends `${infer First}_${infer Letter}${infer Rest}`
? `${First}${Capitalize<Letter>}${CamelCase<Rest>}`
: STR
type TestCamelCase = CamelCase<'hello_world_of_typescript'> // 'helloWorldOfTypescript'
See playground
Let's break it down.
This generic type takes a string type as the generic parameter STR
. It then checks if STR
matches a certain pattern with an underscore followed by some characters.
If it does, it infers substrings from that pattern. Extracting the part before the underscore as First
, the character after the underscore as Letter
, and the rest of the string as Rest
. Otherwise, it returns the string as is.
Then it builds a new string by combining First
, the capitalized Letter
, and Rest
. This process repeats recursively until there are no more underscores left.
With that in place, finishing up is a breeze:
type CamelCase<STR extends string> =
STR extends `${infer First}_${infer Letter}${infer Rest}`
? `${First}${Capitalize<Letter>}${CamelCase<Rest>}`
: STR
type CasedStrings<STR extends string> = {
original: STR,
upperCased: Uppercase<STR>
camelCased: CamelCase<STR>
}
const myString: CasedStrings<'hello_world'> = {
original: 'hello_world',
upperCased: 'HELLO_WORLD',
camelCased: 'helloWorld',
} as const
See playground
For convenience, you may want a function to automate this process:
function transformString<STR extends string>(string: STR): CasedStrings<STR> {
return {} as unknown as CasedStrings<STR> // placeholder for actual implementation
}
const transformedString = transformString('hello_world')
transformedString.original // type: 'hello_world'
transformedString.upperCased // type: 'HELLO_WORLD'
transformedString.camelCased // type: 'helloWorld'
See playground