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.
CodePudding user response:
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 Replace
ments 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!
CodePudding user response:
here is an example of how we can do this for a single type
type B = 'youku-frame';
type Replace<S extends string> = S extends `${infer A}-${infer B}`
? `${Uppercase<A>}_${Uppercase<B>}`
: ${Uppercase<B>};
type C = Replace<B>;
References