TypeScript enum: liczbowy, tekstowy, const i alternatywy | We.Inc
Wygeneruj enumy liczbowe, tekstowe i const z własnych nazw członków, zobacz dokładny JavaScript, który generuje każdy z nich, i porównaj je z obiektami as const oraz uniami literałów.
Enum nadaje zbiorowi nazwanych stałych jeden typ. Enumy liczbowe liczą od 0 w górę i mapują też liczby z powrotem na nazwy, enumy tekstowe wymagają literału dla każdego członka i nie mają odwrotnego mapowania, a const enumy są wstawiane w miejscu użycia i znikają. W odróżnieniu od większości TypeScript zwykłe enumy generują prawdziwy JavaScript, dlatego wiele zespołów woli obiekty as const.
Pięć sposobów modelowania stałego zbioru wartości
Styl
Generuje JavaScript?
Odwrotne mapowanie
Przyjmuje surowy literał?
Enum liczbowy
Tak, obiekt
Tak, z liczby na nazwę
Liczby pasujące do członka
Enum tekstowy
Tak, obiekt
Nie
Nie, trzeba użyć Enum.Member
const enum
Nie, wartości wstawione w miejscu użycia
Nie
Tak jak jego rodzaj enuma
Obiekt as const
Tak, zwykły obiekt
Nie (napisz je, jeśli potrzeba)
Tak
Unia literałów
Nie, usuwana
Nie
Tak
Wpisz nazwy członków do generatora i przełączaj się między stylami. Generator pisze deklarację TypeScript i JavaScript, który wygenerowałby kompilator, więc widzisz koszt każdego wyboru, zanim trafi do Twojej paczki.
Wpisz nazwy członków oddzielone przecinkami, na przykład Draft, Review, Live.
Dla enumów liczbowych ustaw liczbę początkową, a kolejni członkowie liczą od niej w górę.
Wybierz styl, aby zobaczyć jego deklarację, wygenerowany JavaScript i sposób użycia.
Skopiuj wersję, która pasuje do Twojego projektu.
Wybieraj enumy tekstowe lub obiekty as const dla wartości, które opuszczają Twój program, takich jak pola API lub kolumny bazy danych. Linia logu z live czyta się łatwiej niż z 2.
Nigdy nie zmieniaj kolejności ani nie wstawiaj członków w środek enuma liczbowego, który jest gdziekolwiek zapisywany. Każda kolejna liczba się przesuwa, a stare zapisane dane znaczą teraz coś innego.
Unikaj const enum w publikowanych bibliotekach. Użytkownicy kompilujący z isolatedModules lub narzędziem usuwającym typy nie mogą wstawić wartości z innego pliku.
Włącz erasableSyntaxOnly, jeśli uruchamiasz pliki .ts przez type stripping w Node: oznaczy enumy, zanim zawiodą w czasie działania.
Najczęściej zadawane pytania
Czym jest odwrotne mapowanie?
Dla enumów liczbowych tsc zapisuje w obiekcie oba kierunki, więc Direction.Up to 0, a Direction[0] to tekst Up. Członkowie tekstowi nie dostają wpisu odwrotnego, bo wartość mogłaby kolidować z nazwą innego członka.
Dlaczego nie mogę przekazać zwykłego tekstu do funkcji, która przyjmuje enum tekstowy?
Członkowie enuma tekstowego to odrębne typy. Kompilator zgłasza, że literału nie można przypisać do enuma, więc wywołujący muszą pisać Status.Draft. Jeśli chcesz, by wywołujący przekazywali literał, użyj zamiast tego unii literałów tekstowych.
Jak iterować po wartościach enuma?
Dla enuma tekstowego Object.values(MyEnum) zwraca wartości. Dla enuma liczbowego obiekt zawiera też klucze odwrotne, więc filtruj: Object.values(MyEnum).filter((v) => typeof v === 'number').
Czy enumy są przestarzałe?
Nie. Nadal są częścią TypeScript. Nowsza opcja erasableSyntaxOnly, dodana w TypeScript 5.8, pozwala po prostu projektom opartym na type stripping ich zabronić, bo enuma nie da się usunąć przez skasowanie adnotacji.
Czy Node.js uruchamia pliki z enumami bezpośrednio?
Nie przy domyślnym type stripping. Dokumentacja Node wymienia deklaracje enum wśród funkcji, które wymagają generowania kodu i nie są obsługiwane w tym trybie, więc skompiluj je przez tsc lub inny transformer albo przejdź na obiekt as const.
Enumy liczbowe: zwarte, ale kruche
Bez inicjalizatorów członkowie są numerowani kolejno 0, 1, 2. Nadaj pierwszemu wartość, na przykład Low = 1, a reszta będzie kontynuować od niej. Wygenerowany obiekt zawiera mapowanie z nazwy na liczbę i z liczby na nazwę.
Ta zwartość jest też ryzykiem. Liczby nic nie znaczą poza Twoim kodem, a dodanie członka w środku po cichu zmienia numerację wszystkiego, co jest za nim.
Enumy tekstowe: czytelne i ścisłe
Każdy członek potrzebuje literału tekstowego, dzięki czemu wartości same się opisują w logach, adresach URL i JSON. Ścisłość działa w obie strony: wartość odczytana z API to tekst, a nie enum, więc i tak potrzebujesz sprawdzenia, zanim potraktujesz ją jako enum.
Wzorzec as const
Literał obiektu oznaczony as const zachowuje swoje dokładne wartości tekstowe jako typy. Połącz go z type Role = (typeof Role)[keyof typeof Role], a dostaniesz obiekt w czasie działania do iteracji oraz typ unii, który przyjmuje zarówno Role.Admin, jak i literał admin.
To zwykły JavaScript z adnotacjami, więc obsłuży go każde narzędzie usuwające typy, a poza obiektem, który napisałeś, nic dodatkowego nie jest generowane.
Trzy rodzaje enumów i co generują
Enum liczbowy z wartością początkową
Mid i High liczą dalej od Low. Wynikowy obiekt mapuje w obie strony.
Enum tekstowy
Każdy członek jest przypisany raz, bez wpisu odwrotnego.
const enum
Deklaracja znika, a każde użycie zamienia się w swoją wartość.
Alternatywy, które można usunąć
Obiekt as const z wyprowadzoną unią
Działa z narzędziami usuwającymi typy, iteruje przez Object.values i przyjmuje surowy tekst.
Zwykła unia, gdy lista w czasie działania nie jest potrzebna
Usuwana w całości, a kompilator nadal odrzuca każdy inny tekst.
Zakaz enumów w projekcie z type stripping
Z tą opcją deklaracja enum jest błędem kompilacji.
Enum liczbowy
Enum tekstowy
const enum
Obiekt as const
Typ unii
Generator enumów
Nazwa typu
Członkowie (oddzieleni przecinkami)
Pierwsza liczba
Styl enuma
TypeScript
Wygenerowany JavaScript
Kopiuj TypeScript
Kopiuj JavaScript
Używaj nazw, które zaczynają się od litery, $ lub _ i zawierają tylko litery, cyfry, $ lub _, bez powtarzania nazw.