Erstatte streng når du oppretter streng-literal unionstype i TypeScript
Jeg har en streng-literal unionstype som ser slik ut:
type LowerCaseNames = 'youku-frame' | 'youku' | 'mini-program' | 'tiktok-frame';
Dette er bare et eksempel, siden min foreningstype er en liste med mer enn 100 tilfeller.
Det jeg trenger å ha, er en ny type hvor jeg ville hatt følgende «verdier» i typen:
type UpperCaseNames = 'YOUKU_FRAME' | 'YOUKU' | 'MINI_PROGRAM' | 'TIKTOK_FRAME';
Så langt bruker jeg TypeScripts Uppercase-type for å få det store bokstaver.
type UpperCaseNames = `${Uppercase<LowerCaseNames>}`;
Det som dette returnerer er en øvrecaset unjonstype, men jeg har fortsatt - i dem i stedet for _. Finnes det en måte for meg å lage en type som jeg kan bruke slik: $ {Replace<Uppercase<LowerCaseNames>>} for å erstatte - med _? Jeg bruker Typescript v4.4.4.
Svar #1
Du kan skrive en egendefinert Replace<T, S, D>-verktøytype som tar en strengliteraltype T og produserer en ny versjon der forekomster av en kildestreng S erstattes med en destinasjonsstreng D. Her er en måte å gjøre det på:
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}`
Det er en tail-rekursiv template-literal-type som bruker en typeparameter A for å akkumuleres resultatet. Hvis T er av formen L+S+R for noen (muligens tom) "venstre del" L og noen (muligens tom) "høyre del" R, så vil du bruke L som den er, erstatte S med D, og deretter fortsette å gjøre Replace-operasjoner på R. Ellers inneholder T ikke S og du vil bare bruke T som den er.
La oss prøve det:
type LowerCaseNames = 'youku-frame' | 'youku' | 'mini-program' | 'tiktok-frame';
type UpperCaseNames = Uppercase<Replace<LowerCaseNames, "-", "_">>
// type UpperCaseNames = "YOUKU" | "YOUKU_FRAME" | "MINI_PROGRAM" | "TIKTOK_FRAME"
Ser bra ut!
Lenke til kode på lekeplass
