2016-05-17 7 views
4

Unterstützt Typescript einen direkten Test auf strukturelle Kompatibilität?Typescript type compatibility test

C# unterstützt die is Operator und Typen Oberfläche IsAssignableFrom(object instance)

if (foo is SomeType) ... 
if (SomeType.IsAssignableFrom(foo)) ... 

Gibt es einen direkten Weg, um diese Art von Kontrolle in Typoskript ausführen oder muss ich für jede der erforderlichen Elemente untersuchen?

instanceof wird wahrscheinlich für den Fall zur Hand tun, aber nicht die strukturelle Kompatibilität zu urteilen, anstatt die Prototyp-Kette zu überprüfen.

Ja ja, ich weiß, Typescript's instanceof ist direkt äquivalent zu C# is Operator. Aber ich habe mit der Spezifikation der strukturellen Typisierung begonnen.

Vielleicht sollte ich ein Quack Methode setzen Object

Antwort

1

Ich glaube, hier die passende Antwort

Nein, aber!

So einfach diese aus dem Weg zu bekommen, besteht Typoskript der Typinformation nur bei der Kompilierung. Es gibt keine Möglichkeit, die strukturelle Gleichheit zur Laufzeit zu überprüfen. Sie können diese Überprüfung natürlich zur Kompilierzeit durchführen, aber das nennt man nur Zuweisung und wahrscheinlich nicht das, wonach Sie fragen.

Lange Rede kurzer Sinn, Sie müssen für die erforderlichen Mitglieder (typischerweise) suchen, aber es gibt ein paar Möglichkeiten, um klug zu sein.


Ab Typoskript 1.6 die Sprache unterstützt user-defined type guards

Diese als Komfort-Funktionen sind wunderbar und ist eine Möglichkeit, sicher einziehe/Angabe von/einen Typ (abhängig von Ihrer bevorzugten Terminologie) zu verfeinern. Sie können das Vorhandensein bestimmter Typen manuell überprüfen, wenn Sie dies auf die übliche Art und Weise tun möchten (.hasOwnProperty und so). Meiner Erfahrung nach sind sie effektiver für die Versendung von Nachrichtentypen. In den meisten Nachrichtenübergabesystemen haben Sie möglicherweise eine type -Eigenschaft. Sie können eine Funktion definieren

function isConfigGetMsg(msg: BaseMessage): msg is ConfigGetMsg { 
    return msg.name === MsgTypes.CONFIG_GET_MSG; 
} 

//and use it as 
if (isConfigGetMsg(msg)){ 
    console.log(msg.key); //key being a ConfigGetMsg only value 
} 

und das wird gut so lange, wie Ihre Nachrichten wohlgeformt sind. Wie Sie sehen können, müssen Sie jedoch nach bestimmten Informationen suchen. Wenn Sie eine allgemeinere Herangehensweise möchten, dann ist dies nicht der Fall.


Wie Sie bereits erwähnt haben, können Sie jedes der erforderlichen Elemente testen. Sie können es selbst machen etwas einfacher durch die vorherige Technik, so etwas zu schaffen:

interface One { 
    a: number 
} 
interface Two extends One { 
    b: string 
} 
function isAssignableTo<T>(potentialObj:Object, target:T) : potentialObj is T { 
    return Object.keys(target).every(key => potentialObj.hasOwnProperty(key)) 
} 

let a: Object = { 
    a: 4, 
    b: 'hello' 
}; 

let b: Two = undefined; 

if(isAssignableTo(a, b)) { 
    b = a; 
} 

die isAssignableTo Funktion hier den entscheidenden Punkt zu sein. Die Richtung, in der die Parameter liegen sollten, ist umstritten, aber auch nicht relevant, also setze sie wie du willst. Dies ist keine ideale Lösung. Möglicherweise möchten Sie, dass Dinge nur auf der Grundlage von Nicht-Funktionseigenschaften zuweisbar sind, z. B. implizierte Zustände und nicht allgemeine Funktionen. Sie könnten versuchen, die Überprüfung zu erweitern, aber es gibt Fallstricke.


Es tut mir leid zu sagen, ich glaube, die einzige "wahre" Antwort ist eine, die noch nicht praktikabel ist. Wenn Sie mit Klassen arbeiten, können Sie Dekoratoren verwenden, um Metadaten über Ihre Anwendung zu erfassen, einschließlich Typinformationen, die später für die Reflektion/Inspektion verwendet werden können. Sie können hierfür Ihre eigenen Dekoratoren erstellen, aber Sie können auch typescript's own metadata generation for class properties. nutzen, die Sie mit einem tsconfig-Flag aktivieren können.

Dies setzt voraus, dass metadata reflection api vorhanden ist. Sie müssen dies verwenden, um diese Informationen zu extrahieren. Sie könnten dann die Funktion isAssignableTo von früher neu schreiben, um von den Metadaten abzuarbeiten. Wenn ich mich richtig erinnere, leidet dies immer noch unter dem Problem, dass Typen als Strings gespeichert werden und wenn Sie dann Subtypen haben, die nicht übereinstimmen.


Wie auch immer, ich hoffe, dass das hilft. Entschuldigung, ich konnte dir kein einfaches Ja geben. Da ich mein Glück kannte, suchten Sie nur nach einer Aufgabe ;).

+0

Nein, Ihre Interpretation war genau richtig. Ich wollte in der Tat eine Kompatibilitätsprüfung für die Laufzeitzuweisung durchführen. Die Anwendung analysiert eine Zeichenfolge aus einer Datenbank. Es begann als ein einziges primitives X. Dann mutierte es zu einem Array [X, Y, Z]. Dann ein Objekt, das einen Komparator und ein Array von Primitiven definiert {"Komparator": "beliebig", "Werte": [X, Y, Z]}. Je nach Alter könnte eine Zeichenfolge all diese Dinge enthalten, also analysiere ich sie als JSON und erkläre dann, was ich vor der Normalisierung von Legacy-Codierungen hatte - ein primitives oder Array von Primitiven liefert die Werte und der Komparator ist "any". –

Verwandte Themen