I have a string literal union type that looks like this:
type LowerCaseNames = 'youku-frame' | 'youku' | 'mini-program' | 'tiktok-frame';
This is only an example, since my union type is a list of more than 100 cases.
What I need to have is a new type where I would have the following "values" in type:
type UpperCaseNames = 'YOUKU_FRAME' | 'YOUKU' | 'MINI_PROGRAM' | 'TIKTOK_FRAME';
So far, I am using TypeScript’s Uppercase type in order to have it upper-cased.
type UpperCaseNames = `${Uppercase<LowerCaseNames>}`;
What this returns is upper-cased union type but, I still have in them - instead of _.
Is there a way for me to create a type that I can use like this ${Replace<Uppercase<LowerCaseNames>>} in order to replace - with _?
I am using Typescript v4.4.4.
>Solution :
You can write a custom Replace<T, S, D> utility type which takes a string literal type T and produces a new version where occurrences of a source string S are replaced with a destination string D. Here’s one way to do it:
type Replace<T extends string, S extends string, D extends string,
A extends string = ""> = T extends `${infer L}${S}${infer R}` ?
Replace<R, S, D, `${A}${L}${D}`> : `${A}${T}`
That’s a tail-recursive template literal type which uses a type parameter A to accumulate the result. If T is of the form L+S+R for some (possibly empty) "left part" L and some (possibly empty) "right part" R, then you want to use L as-is, replace S with D, and then continue doing Replacements on R. Otherwise, T doesn’t contain S and you just want to use T as-is.
Let’s try it out:
type LowerCaseNames = 'youku-frame' | 'youku' | 'mini-program' | 'tiktok-frame';
type UpperCaseNames = Uppercase<Replace<LowerCaseNames, "-", "_">>
// type UpperCaseNames = "YOUKU" | "YOUKU_FRAME" | "MINI_PROGRAM" | "TIKTOK_FRAME"
Looks good!