reactjs - Is er een manier om een string literal union type te maken van een object in Typescript?
const FOO_TYPES={ FOO:'foo', FAA:'faa' }Ik wil het bovenstaande object gebruiken om programmatisch het volgende type te creëren:
type FooTypes = "foo" | "faa"Zodat TypeScript een fout kan geven als een andere waarde dan de opgegeven wordt geleverd.
Ik heb een soortgelijke situatie waarbij ik het type van het object krijg, zoals volgt:
type ObjectValues<T>=T[keyof T]Maar in dit geval zal TypeScript alleen het type verwachten en niet controleren op de toegestane waarden.
Antwoord #1
Je moet veranderen hoe je FOO_TYPES initialiseert. In jouw versie:
const FOO_TYPES = { FOO: 'foo', FAA: 'faa' };
/* const FOO_TYPES: {
FOO: string;
FAA: string;
} */
de compiler leidt het type {FOO: string, FAA: string} af voor die variabele. Dit is vaak wat mensen willen wanneer ze een variabele initialiseren, aangezien iemand redelijkerwijs andere string-waarden aan de eigenschappen zou willen toewijzen, zoals FOO_TYPES.FAA='blah';. Maar dat is hier niet wat je wilt; in het bovenstaande type is de compiler de specifieke letterlijke types "foo" en "faa" vergeten, en er is geen manier om ze terug te halen. Dus als je wilt dat de compiler deze types onthoudt, moet je voorkomen dat hij uitbreidt.
Een gemakkelijke manier om dat gedrag te krijgen is door een const-assertie op de initializer te gebruiken:
const FOO_TYPES = { FOO: 'foo', FAA: 'faa' } as const;
/* const FOO_TYPES: {
readonly FOO: "foo";
readonly FAA: "faa";
} */
Dit vertelt de compiler dat je van plan bent FOO_TYPES te behandelen als een enigszins onveranderlijk datatype, waarbij de eigenschappen niet zullen veranderen nadat ze zijn ingesteld. En het leidt een nauwere type af voor elke waarde, inclusief de "foo" en "faa" letterlijke types die je wilt.
Zodra je dat doet, is het eenvoudig om FooTypes te definiëren in termen van de typeof FOO_TYPES:
type FooTypes = ObjectValues<typeof FOO_TYPES>;
// type FooTypes = "foo" | "faa"
Speeltuinlink naar code
