Zdefiniowałem następujące wyliczenie w TypeScript:
enum Color{
Red, Green
}
Teraz w mojej funkcji otrzymuję kolor jako ciąg. Wypróbowałem następujący kod:
var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum
Jak przekonwertować tę wartość na wyliczenie?
typescript
Amitabh
źródło
źródło
--noImplicitAny
(w VS niezaznaczone „Zezwól domyślnie na dowolne” typy). To produkujeerror TS7017: Index signature of object type implicitly has an 'any' type.
dla mnie to działało:var color: Color = (<any>Color)[green];
(testowane z wersją 1.4)var color : Color = Color[green as keyof typeof Color];
Od Typescript 2.1 klucze ciągowe w wyliczeniach są silnie typowane.
keyof typeof
służy do uzyskania informacji o dostępnych kluczach łańcuchowych ( 1 ):https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
źródło
let s = "Green"; let typedColor = <keyof typeof Color> s;
let
goconst
będzie działać bez rzucania. Zaktualizowany przykład, aby to wyjaśnić. Dzięki @SergeyTtypedColorString = Color["Black"];
teraz powracaerror TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'
const color: Color = Color[colorString as keyof typeof Color];
Jeśli masz pewność, że łańcuch wejściowy ma dokładne dopasowanie do wyliczenia koloru, użyj:
W przypadku, gdy ciąg wejściowy może nie pasować do Enum, użyj:
Plac zabaw
Jeśli nie przerzucimy
enum
do<any>
pisania, TypeScript wyświetli błąd:Oznacza to, że domyślnie typ Enum TypeScript działa z indeksami liczbowymi, tj.
let c = Color[0]
Ale nie z takimi jak indeksy łańcuchowelet c = Color["string"]
. Jest to znane ograniczenie zespołu Microsoft dotyczące bardziej ogólnego problemu Indeksy ciągów obiektów .źródło
typeof '0'
powinno byćstring
Ten przykład działa z
--noImplicitAny
TypeScriptŹródła:
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
źródło
Ta uwaga dotyczy basarat za odpowiedź , a nie oryginalne pytanie.
Miałem dziwny problem w swoim własnym projekcie, w którym kompilator dawał błąd w przybliżeniu odpowiadający „nie można przekonwertować ciągu na kolor” przy użyciu odpowiednika tego kodu:
Odkryłem, że wnioskowanie o typie kompilatora jest mylące, i pomyślałem, że
colorId
jest to wartość wyliczana, a nie identyfikator. Aby rozwiązać problem, musiałem rzucić identyfikator jako ciąg znaków:Nie jestem pewien, co spowodowało problem, ale zostawię tę notatkę tutaj na wypadek, gdyby ktoś napotkał ten sam problem, co ja.
źródło
Mam go działa przy użyciu następującego kodu.
źródło
Jeśli podasz wartości ciągu do swojego wyliczenia, rzut prosty działa dobrze.
źródło
const colorEnum = "Blue" as Color
nie popełni błędu, i będziesz myśleć, żecolorEnum
jest OK. Ale gdybyś doconsole.log
tego doszedł, zobaczyłbyś „niebieski”. Odpowiedź Artru jest miła, ponieważcolorEnum
będzieundefined
- i możesz to sprawdzić konkretnie.Biorąc pod uwagę, że używasz maszynopisu: wiele z powyższych rozwiązań może nie działać lub jest zbyt skomplikowanych.
Sytuacja : ciągi znaków nie są takie same jak wartości wyliczeniowe (obudowa różni się)
Po prostu użyj:
źródło
Wystąpił również ten sam błąd kompilatora. Tylko nieznacznie krótsza odmiana podejścia Sly_cardinal.
źródło
myProp.color = Color[<string><any>myProp.color]
PozdrowieniaJeśli kompilator TypeScript wie, że typ zmiennej jest ciągiem, działa to:
W przeciwnym razie powinieneś jawnie przekonwertować go na ciąg znaków (aby uniknąć ostrzeżeń kompilatora):
W czasie wykonywania oba rozwiązania będą działać.
źródło
<string>colorName
zamiast tego typecasta"" + colorName
?W tym pytaniu jest wiele mieszanych informacji, dlatego omówmy całą implementację dla TypeScript 2.x + w Przewodniku Nicka dotyczącym korzystania z wyliczeń w modelach z TypeScript .
Ten przewodnik jest przeznaczony dla: osób tworzących kod po stronie klienta, który pobiera zestaw znanych ciągów z serwera, który byłby wygodnie modelowany jako Enum po stronie klienta.
Zdefiniuj wyliczenie
Zacznijmy od wyliczenia. Powinno to wyglądać mniej więcej tak:
Warto zwrócić uwagę na dwie rzeczy:
Wyraźnie deklarujemy je jako przypadki wyliczenia oparte na łańcuchach znaków, co pozwala nam tworzyć ich wystąpienia za pomocą łańcuchów, a nie innych niepowiązanych liczb.
Dodaliśmy opcję, która może lub nie może istnieć na nasz model serwera:
UNKNOWN
. Można sobie z tym poradzić takundefined
, jak wolisz, ale| undefined
w miarę możliwości lubię unikać typów, aby uprościć obsługę.Wspaniałą rzeczą w posiadaniu
UNKNOWN
sprawy jest to, że możesz być naprawdę oczywisty w kodzie i tworzyć style dla nieznanych przypadków wyliczeniowych jasnoczerwonych i mrugających, abyś wiedział, że nie radzisz sobie z czymś poprawnie.Analizuj wyliczenie
Być może używasz tego wyliczenia osadzonego w innym modelu lub zupełnie osobno, ale będziesz musiał przeanalizować wyliczenie napisane ciągiem Y z JSON lub XML (ha) w silnie napisanym odpowiedniku. Parser ten osadzony w innym modelu żyje w konstruktorze klas.
Jeśli wyliczenie zostanie poprawnie przeanalizowane, zakończy się poprawnym typem. W przeciwnym razie będzie
undefined
i możesz go przechwycić i zwrócić swojąUNKNOWN
sprawę. Jeśli wolisz używaćundefined
jako swojego nieznanego przypadku, możesz po prostu zwrócić dowolny wynik z parsowanej analizy enum.Stamtąd jest tylko kwestia użycia funkcji analizy składni i użycia nowej, silnie wpisanej zmiennej.
źródło
IssueType["REPS"]="REPS"
. Jeśli zdefiniowałeś swój enum trochę inaczej, powiedzmy,REPS="reps"
to dałoby to,IssueType["REPS"]="reps"
co ...IssueType.UNKNOWN
ponieważreps
w twoim wyliczeniu nie ma klucza . Szkoda, wciąż nie znalazłem działającego rozwiązania, ponieważ moje ciągi zawierają łączniki, co czyni je bezużytecznymi jako klucze.Musiałem wiedzieć, jak ominąć wartości wyliczeniowe (testowałem wiele permutacji kilku wyliczeń) i stwierdziłem, że działa dobrze:
Źródło: https://blog.mikeski.net/development/javascript/typescript-enums-to-from-string/
źródło
each
do testowania każdego przypadku enum tylko jedną metodąSzukałem odpowiedzi, która może uzyskać
enum
odstring
, ale w moim przypadku wartości wyliczone miały inny odpowiednik wartości ciągu. OP miał prosty wyliczenieColor
, ale miałem coś innego:Gdy próbujesz rozwiązać
Gender.CantTell
za pomocą"Can't tell"
łańcucha, zwracaundefined
on oryginalną odpowiedź.Kolejna odpowiedź
Zasadniczo wpadłem na inną odpowiedź, silnie zainspirowaną tą odpowiedzią :
Notatki
filter
, przy założeniu, że klient przechodzi ważny ciąg z wyliczenia. Jeśli tak nie jest,undefined
zostanie zwrócone.enumObj
naany
, ponieważ w TypeScript 3.0+ (obecnie używa TypeScript 3.5),enumObj
jest rozwiązany jakounknown
.Przykład użycia
Uwaga: I, jak ktoś zauważył w komentarzu, chciałem również użyć
noImplicitAny
.Zaktualizowana wersja
Brak obsady
any
i poprawne pisanie.Zaktualizowana wersja ma również łatwiejszy sposób nazywania i jest bardziej czytelna:
źródło
Enum
Przykładowe użycie
Zignoruj analizę składni z rozróżnianiem wielkości liter
źródło
return enumType[property];
Skills = "anyvalue"
Wyliczenia utworzone w ten sposób zostały skompilowane w obiekt, który przechowuje oba do przodu
(name -> value)
(value -> name)
mapowanie do i do tyłu . Jak możemy zobaczyć z tego chromowanego zrzutu devtools:Oto przykład działania podwójnego mapowania i sposobu przesyłania z jednego do drugiego:
źródło
Spróbuj tego
Działa to dobrze w wersji 3.5.3
źródło
Jeśli używasz przestrzeni nazw w celu rozszerzenia funkcjonalności Twojego wyliczenia, możesz również zrobić coś takiego
i użyj tego w ten sposób
źródło
inna odmiana może być
źródło