2017-10-12 39 views
8

Napisałem ten kodDlaczego "instanceof" w TypeScript daje mi błąd "" Foo "odnosi się tylko do typu, ale jest tutaj używane jako wartość."?

interface Foo { 
    abcdef: number; 
} 

let x: Foo | string; 

if (x instanceof Foo) { 
    // ... 
} 

Ale maszynopis dał mi ten błąd:

'Foo' only refers to a type, but is being used as a value here. 

Dlaczego tak się dzieje? Pomyślałem, że instanceof może sprawdzić, czy moja wartość ma określony typ, ale TypeScript wydaje się tego nie lubić.

+0

Zobacz odpowiedź poniżej @ 4castle. W przeciwnym razie masz rację, zrobię to 'Foo | string'. –

+1

Możliwy duplikat [sprawdzania typu interfejsu za pomocą maszynopisu] (https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) – Cerbrus

+0

I możliwy duplikat [Sprawdź, czy zmienna jest określonym typem interfejsu w maszynopisarstwo] (https://stackoverflow.com/questions/29172486/check-if-variable-is-a-specific-interface-type-in-a-typescript-union) (nie bardzo chcę pojedynczo własnoręcznie to wymusić) – Cerbrus

Odpowiedz

17

Co się dzieje

Problem jest, że instanceof jest konstruktem z JavaScript, a w JavaScript, instanceof oczekuje wartości dla argumentu po prawej stronie. W szczególności w języku x instanceof Foo JavaScript wykona kontrolę w czasie wykonywania, aby sprawdzić, czy Foo.prototype istnieje w dowolnym miejscu w prototypowym łańcuchu x.

Jednak w TypeScript, interface s nie emitują. Oznacza to, że Foo.prototype nie istnieje w środowisku wykonawczym, więc ten kod na pewno się nie powiedzie.

TypeScript próbuje dać ci tam ostrzeżenie: Foo to tylko typ; to nie jest żadna wartość!

"Co mogę zrobić zamiast instanceof?"

Możesz zajrzeć do type guards and user-defined type guards.

"Ale co, jeśli po prostu przełączyłem z interface na class?"

może ulec pokusie, aby przełączyć się z interface do class, ale należy zdać sobie sprawę, że w systemie typu strukturalnego maszynopis w (gdzie rzeczy są przede wszystkim kształt oparty) można produkować każdy obiekt, który ma taki sam kształt jak dana klasa:

class C { 
    a: number = 10; 
    b: boolean = true; 
    c: string = "hello"; 
} 

let x = new C() 
let y = { 
    a: 10, b: true, c: "hello", 
} 

// Works! 
x = y; 
y = x; 

W tym przypadku, trzeba x i y, które mają ten sam typ, ale jeśli spróbuj instanceof na jeden z nich, dostaniesz odwrotny skutek na drugiej. Tak więc instanceof nie będzie naprawdę powiedzieć wiele o typie, jeśli korzystasz z typów strukturalnych w TypeScript.

+0

Zajęłbym mnie wiekiem, aby znaleźć to dla siebie ! – series0ne