Überprüfung des Klassentyps in TypeScript


240

In ActionScript ist es möglich, den Typ zur Laufzeit mit dem Operator is zu überprüfen :

var mySprite:Sprite = new Sprite(); 
trace(mySprite is Sprite); // true 
trace(mySprite is DisplayObject);// true 
trace(mySprite is IEventDispatcher); // true

Ist es möglich zu erkennen, ob eine Variable (erweitert oder) eine bestimmte Klasse oder Schnittstelle mit TypeScript ist?

Ich konnte nichts darüber in den Sprachspezifikationen finden. Es sollte vorhanden sein, wenn mit Klassen / Schnittstellen gearbeitet wird.

Antworten:


318

4.19.4 Die Instanz des Operators

Der instanceofOperator erfordert, dass der linke Operand vom Typ Any, ein Objekttyp oder ein Typparametertyp und der rechte Operand vom Typ Any oder ein Subtyp vom Schnittstellentyp 'Function' ist. Das Ergebnis ist immer vom primitiven Typ Boolean.

Also könntest du verwenden

mySprite instanceof Sprite;

Beachten Sie, dass dieser Operator auch in ActionScript enthalten ist, dort jedoch nicht mehr verwendet werden sollte:

Mit dem für ActionScript 3.0 neuen Operator is können Sie testen, ob eine Variable oder ein Ausdruck Mitglied eines bestimmten Datentyps ist. In früheren Versionen von ActionScript stellte der Operator instanceof diese Funktionalität bereit. In ActionScript 3.0 sollte der Operator instanceof jedoch nicht zum Testen der Datentypzugehörigkeit verwendet werden. Der Operator is sollte anstelle des Operators instanceof für die manuelle Typprüfung verwendet werden, da der Ausdruck x instanceof y lediglich die Prototypkette von x auf das Vorhandensein von y überprüft (und in ActionScript 3.0 liefert die Prototypkette kein vollständiges Bild von die Vererbungshierarchie).

TypeScript's instanceof die gleichen Probleme. Da es sich um eine Sprache handelt, die sich noch in der Entwicklung befindet, empfehle ich Ihnen, einen Vorschlag für eine solche Einrichtung vorzulegen.

Siehe auch:


54

Mit TypeScript können Sie den Typ einer Variablen zur Laufzeit überprüfen. Sie können eine Validierung Funktion hinzufügen , die ein zurückgibt Typen Prädikat . Sie können diese Funktion also in einer if-Anweisung aufrufen und sicherstellen, dass der gesamte Code in diesem Block sicher als der Typ verwendet werden kann, den Sie für richtig halten.

Beispiel aus den TypeScript-Dokumenten:

function isFish(pet: Fish | Bird): pet is Fish {
   return (<Fish>pet).swim !== undefined;
}

// Both calls to 'swim' and 'fly' are now okay.
if (isFish(pet)) {
  pet.swim();
}
else {
  pet.fly();
}

Weitere Informationen finden Sie unter: https://www.typescriptlang.org/docs/handbook/advanced-types.html


29
Dies ist keine Laufzeit-Typüberprüfung, sondern nur eine Überprüfung, ob ein Objekt eine bestimmte Eigenschaft hat. Dies mag für Gewerkschaftstypen nützlich sein, funktioniert also für diesen speziellen Fall, aber es ist nicht wirklich machbar, für alles wie dieses ein "isThingy" zu erstellen. Auch wenn sowohl Fisch als auch Vogel schwimmen könnten, wären Sie zum Scheitern verurteilt. Ich bin froh, dass ich Haxe verwende, das über eine zuverlässige Typprüfung verfügt, die Sie Std.is(pet, Fish)für Typen, Schnittstellen usw. verwenden können.
Mark Knol

4
Ich fand diese Antwort hilfreich, aber ich denke, Sie könnten sie etwas genauer anpassen. Das isFishSelbst ist das Prädikat, das erstellt wird, und sein Körper muss kein Einzeiler-Prädikat sein. Dies hat den Vorteil, dass der Compiler zur Kompilierungszeit die entsprechenden möglichen Funktionen versteht, Ihr Code isFishjedoch zur Laufzeit ausgeführt wird. Sie könnten sogar den Guard eine instanceofAnweisung enthalten lassen , z. B. return pet instanceof Fish(vorausgesetzt, es handelt sich um eine Klasse und keine Schnittstelle), dies wäre jedoch unnötig, da der Compiler dies instanceofdirekt versteht .

4
Dies wird auch als "User Defined Type Guards" bezeichnet, siehe basarat.gitbooks.io/typescript/content/docs/types/…
Julian

@MarkKnol Es handelt sich tatsächlich um eine Laufzeitprüfung, die jedoch hinsichtlich des Typoskripts die Fähigkeit bietet, den abgeleiteten Typ zu verstehen (was bedeutet: Sie können mir vertrauen, dass dies Typ X oder Y ist, da ich ihn zur Laufzeit testen werde).
Flavien Volken

3
Möglicherweise möchten Sie die Verwendung in Betracht ziehen, (pet as Fish)da sich der tslinter darüber beschwert (<Fish>pet). Siehe tslint doc
Bryan

1

Hierfür können Sie den instanceofOperator verwenden. Von MDN:

Die Instanz des Operators testet, ob die Prototyp-Eigenschaft eines Konstruktors irgendwo in der Prototyp-Kette eines Objekts angezeigt wird.

Wenn Sie nicht wissen, welche Prototypen und Prototypenketten es sind, empfehle ich dringend, sie nachzuschlagen. Auch hier ist ein JS-Beispiel (TS funktioniert in dieser Hinsicht ähnlich), das das Konzept verdeutlichen könnte:

    class Animal {
        name;
    
        constructor(name) {
            this.name = name;
        }
    }
    
    const animal = new Animal('fluffy');
    
    // true because Animal in on the prototype chain of animal
    console.log(animal instanceof Animal); // true
    // Proof that Animal is on the prototype chain
    console.log(Object.getPrototypeOf(animal) === Animal.prototype); // true
    
    // true because Object in on the prototype chain of animal
    console.log(animal instanceof Object); 
    // Proof that Object is on the prototype chain
    console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
    
    console.log(animal instanceof Function); // false, Function not on prototype chain
    
    

Die Prototypkette in diesem Beispiel lautet:

Tier> Tierprototyp> Objektprototyp

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.