Bygging av en type basert på nøklene til en const i Typescript
Jeg har en ordbok med MessageTemplates som jeg bygger opp over tid, og jeg håpet at jeg deretter kunne eksportere en type i TypeScript som representerer settet av egenskaper som henger på MessageTemplates-strukturen, men den protesterer.
Føler at jeg gjør noe dumt, men jeg har sett på dette for lenge til at jeg ikke kan spørre.
Merk, jeg fant nettopp ut at hvis jeg bruker en Klasse-struktur - med statiske metoder som henger på den - så fungerer det, men jeg er fortsatt forvirret over hvorfor den vanlige objekt-literal syntaksen ikke fungerer.
Svar #1
Problemet du har er at MessageTemplates er en verdi, ikke en type, og keyof-indekstype-spøroperatøren virker på navnet til en type, ikke en verdi. En tommelfingerregel for å skille dem er å finne ut om navnet vil vises i den kompilerte JavaScript-koden eller ikke. Hvis det vises ved kjøretid, er det sannsynligvis en verdi; hvis ikke, er det sannsynligvis en type. I ditt tilfelle vil MessageTemplates eksistere som en variabel ved kjøretid, så det er en verdi.
Det du vil bruke keyof på er ikke MessageTemplates, men typen til verdien MessageTemplates. Og heldigvis kan du bruke typeforespørselsoperatoren typeof for å få typen til en verdi. Så typeof X for en verdi som heter X returnerer typen til den verdien.
(Dette skal ikke forveksles med runtime-operatoren typeof, hvor typeof X virker på en verdi som heter X og returnerer en streng som "number" eller "boolean" ved runtime. Du kan se hvilken som er hvilken fra konteksten. Hvis typeof vises i den kompilerte JavaScript-koden, er det runtime-operatoren. Hvis typeof er en del av en typeannotasjon eller deklarasjon og blir fjernet før kompilering til JavaScript, er det typeforespørselsoperatoren. Beklager; det er forvirrende å bruke det samme nøkkelordet for forskjellige ting, men sånn er det. Jeg antar at språkdesignerne foretrekker å gjenbruke allerede reserverte nøkkelord slik at de ikke bryter eksisterende JavaScript-kode. Eller så synes de det er gøy å få folk til å legge til alle disse forbeholdene i forklaringene sine.)
For å oppsummere: du vil ikke ha keyof MessageTemplates, men "keyof typen til MessageTemplates", som er keyof (typeof MessageTemplates). Du kan fjerne parentesene: keyof typeof MessageTemplates:
export type IMessageTemplateType = keyof typeof MessageTemplates
// type IMessageTemplateType = "upcomingUpload" | ...
Håper det hjelper. Lykke til!
