To pytanie jest bezpośrednim sprawdzeniem analogonu do klasy za pomocą TypeScript
Muszę dowiedzieć się w czasie wykonywania, czy zmienna typu any implementuje interfejs. Oto mój kod:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
Jeśli wpiszesz ten kod na placu zabaw maszynopisu, ostatni wiersz zostanie oznaczony jako błąd: „Nazwa A nie istnieje w bieżącym zakresie”. Ale to nieprawda, nazwa istnieje w obecnym zakresie. Mogę nawet zmienić deklarację zmiennej na var a:A={member:"foobar"};
bez reklamacji redaktora. Po przejrzeniu sieci i znalezieniu drugiego pytania na SO zmieniłem interfejs na klasę, ale potem nie mogę używać literałów obiektowych do tworzenia instancji.
Zastanawiałem się, jak typ A może tak zniknąć, ale spojrzenie na wygenerowany skrypt javascript wyjaśnia problem:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
Nie ma reprezentacji A jako interfejsu, dlatego nie jest możliwe sprawdzenie typu środowiska wykonawczego.
Rozumiem, że javascript jako język dynamiczny nie ma pojęcia interfejsów. Czy jest jakiś sposób na sprawdzenie typu dla interfejsów?
Automatyczne uzupełnianie placu zabaw maszynopisu ujawnia, że maszynopis oferuje nawet metodę implements
. Jak mogę tego użyć?
Odpowiedzi:
Możesz osiągnąć to, co chcesz bez
instanceof
słowa kluczowego, ponieważ możesz teraz pisać zabezpieczenia typu niestandardowego:Wielu członków
Jeśli musisz sprawdzić wiele członków, aby ustalić, czy obiekt pasuje do twojego typu, możesz zamiast tego dodać dyskryminator. Poniższy przykład jest najbardziej podstawowym przykładem i wymaga zarządzania własnymi dyskryminatorami ... musisz pogłębić wzorce, aby uniknąć duplikowania dyskryminatorów.
źródło
isInstanceOfA(instantiatedB)
zwrócić wartość true, ale chciałbyśisInstanceOfB(instantiatedA)
zwrócić wartość false. Aby to drugie miało miejsce, czy dyskryminator B nie musiałby być „I-AM-A”?W TypeScript 1.6 strażnik typów zdefiniowany przez użytkownika wykona zadanie.
I tak jak wspomniał Joe Yang: od TypeScript 2.0 możesz nawet skorzystać z oznaczonego typu unii.
I to też działa
switch
.źródło
object is type
iobject instanceof class
polega na tym, że typ w TypeScript jest strukturalny, obchodzi go tylko „kształt” zamiast tego, skąd obiekt uzyskał kształt: zwykły obiekt lub instancja klasy, to nie ma znaczenia.type
właściwości. W takim przypadku to działa. Ten przykład nie pokazuje tego faktu.maszynopis 2.0 wprowadza oznaczony związek
Funkcje maszynopisu 2.0
źródło
Co powiesz na zdefiniowane przez użytkownika zabezpieczenia typu? https://www.typescriptlang.org/docs/handbook/advanced-types.html
źródło
(pet as Fish).swim !== undefined;
.Jest to teraz możliwe, właśnie wydałem ulepszoną wersję
TypeScript
kompilatora, która zapewnia pełne możliwości odbicia. Możesz tworzyć instancje klas z ich obiektów metadanych, pobierać metadane z konstruktorów klas i sprawdzać interfejs / klasy w czasie wykonywania. Możesz to sprawdzić tutajPrzykład użycia:
W jednym ze swoich plików maszynopisu utwórz interfejs i klasę, która implementuje go w następujący sposób:
teraz wydrukujmy listę zaimplementowanych interfejsów.
skompiluj z reflec-ts i uruchom:
Szczegółowe informacje na temat
Interface
meta-typów znajdują się na stronie reflection.d.ts .AKTUALIZACJA: Pełny przykład działa tutaj
źródło
implements
ale chciałemtak samo jak powyżej, gdzie zastosowano zabezpieczenia zdefiniowane przez użytkownika, ale tym razem z predykatem funkcji strzałki
źródło
Oto kolejna opcja: moduł ts-interface-builder zapewnia narzędzie do kompilacji, które konwertuje interfejs TypeScript na deskryptor środowiska wykonawczego, a ts-interface-checker może sprawdzić, czy obiekt go spełnia.
Na przykład OP
Najpierw uruchomisz,
ts-interface-builder
który tworzy nowy zwięzły plik z deskryptorem, powiedzmyfoo-ti.ts
, którego możesz użyć w następujący sposób:Możesz utworzyć jednokierunkową funkcję ochrony typu:
źródło
Chciałbym zauważyć, że TypeScript nie zapewnia bezpośredniego mechanizmu do dynamicznego testowania, czy obiekt implementuje określony interfejs.
Zamiast tego kod TypeScript może korzystać z techniki JavaScript do sprawdzania, czy w obiekcie znajduje się odpowiedni zestaw elementów. Na przykład:
źródło
for (element in obj) {}
), Aby sprawdzić, czy dwa obiekty mają podobne elementy podobnych typów.TypeGuards
źródło
W oparciu o odpowiedź Fentona , oto moja implementacja funkcji sprawdzającej, czy dana
object
ma klucze iinterface
ma, zarówno w pełni, jak i częściowo.W zależności od przypadku użycia może być konieczne sprawdzenie typów właściwości każdego interfejsu. Poniższy kod tego nie robi.
Przykład użycia:
źródło
źródło
Ponieważ typ jest nieznany w czasie wykonywania, napisałem kod w następujący sposób, aby porównać nieznany obiekt, nie z typem, ale z obiektem znanego typu:
Oto kod (niezależny od interfejsu), którego używam do głębokiego porównania:
Poniżej znajduje się przykład tego, jak go używam.
W tym przykładzie oczekuję, że JSON zawiera tablicę krotek, z których drugi element jest instancją interfejsu o nazwie
User
(która ma dwa opcjonalne elementy).Sprawdzanie typu TypeScript zapewni, że mój przykładowy obiekt jest poprawny, a następnie funkcja assertTypeT sprawdzi, czy nieznany (załadowany z JSON) obiekt pasuje do obiektu przykładowego.
Możesz wywołać taką kontrolę w implementacji funkcji ochrony zdefiniowanej przez użytkownika.
źródło
Możesz sprawdzić typ TypeScript w czasie wykonywania, używając ts-validate-type , podobnie jak to (wymaga wtyczki Babel):
źródło