2

Ich studiere gerade strukturelle Typisierung. Ich bin skeptisch gegenüber der Vorstellung, dass zwei Typen gleichwertig sind, nur weil sie einen Teil ihrer Struktur gemeinsam haben. Dies fühlt sich sehr ähnlich wie die statische Eingabe von Enten an und ignoriert vollständig die semantische Ebene der Typen. Also nahm ich einen genaueren Blick auf Fluss struktureller Typisierung von gewöhnlichen Objekten und habe folgendes Verhalten auftreten:"Unterläuft" die strukturelle Subtypisierung von Flows bestimmten Subtype-Eigenschaften?

const o:{} = {foo: true}; 
o.foo; // type error 

{} ist ein Strukturtyp und der übergeordnete Typ von allen gewöhnlichen Objekten. Daher macht es Sinn, dass ich damit o annotieren kann, weil {foo: true} ein struktureller Subtyp von {} ist. Wenn ich versuche, auf die vorhandene foo-Eigenschaft zuzugreifen, gibt diese Operation jedoch keine Überprüfung ein. Das ist seltsam, weil AFAIK, ein Struktur-Subtyp, normalerweise bestimmte Eigenschaften enthalten kann, solange er auch alle erforderlichen Eigenschaften seines Supertyps enthält.

Es scheint, als würde der strukturelle Subtyping-Algorithmus des Flusses gelegentlich Eigenschaften vergessen, die für einen bestimmten Subtyp spezifisch sind. Ist dieses Verhalten beabsichtigt oder bin ich gerade in einen Randfall geraten?

+1

Könnten Sie klarstellen, was Sie meinen? Wenn Sie den Typ ': {}' deklarieren, haben Sie explizit die Typinformationen darüber gelöscht, genau wie wenn Sie 'Tier foo = new Cat()', 'foo' nicht wissen, dass es sich um eine' Katze' handelt weiß nur, dass es ein 'Tier' ist. – loganfsmyth

+0

@loganfsmyth '{}' ist nur der allgemeinste gewöhnliche Objekttyp ohne Struktur. Es ist natürlich ziemlich nutzlos.Die Frage ist, ob das Verhalten, das ich mit diesem Randfall beobachtet habe, Teil eines tieferen Problems ist, das spezifisch für Subtyping ist. – ftor

+1

Was ich versuche zu klären ist, was ist mit diesem Fall, siehst du einen Randfall, und was wäre damit ein Problem? Im Fall von JavaScript als einer nicht typisierten Sprache gibt es absolut Fälle, in denen Sie ein Objekt haben und nichts über seine Eigenschaften wissen. Um auf 'foo' zu kommen, kannst du' if (typeof o.foo === "boolean") {/ * mit der Eigenschaft als boolesches * /} erledigen und es wird großartig funktionieren. – loganfsmyth

Antwort

3

Das allgemeine Problem, das Sie beschreiben, ist eine Tatsache, von einem Subtyp auf einen Supertyp zu übertragen. Durch das Ausführen der Umwandlung weisen Sie den Compiler explizit an, Informationen über ein bestimmtes Objekt zu verwerfen.

Zum Beispiel, auch ohne strukturelle Typisierung, wenn Sie

tun
class Animal {} 

class Cat extends Animal { 
    foo: bool = true; 
} 

const c: Animal = new Cat(); 

console.log(c.foo); 

(On flow.org/try)

es nicht aus dem gleichen Grund typecheck. In Ihrem Beispiel haben Sie dem Compiler explizit gesagt "bedenken Sie o, um den Typ {} zu haben", genau wie in meinem Beispiel habe ich gesagt "bedenken Sie c, um den Typ Animal zu haben". Aus diesem Grund wurde der Compiler explizit aufgefordert zu vergessen, dass es mit einer Cat arbeitet, daher vergisst es, dass das Objekt eine .foo Eigenschaft hat.

Es scheint, als würde der strukturelle Subtyping-Algorithmus des Flusses gelegentlich Eigenschaften vergessen, die für einen bestimmten Subtyp spezifisch sind. Ist dieses Verhalten beabsichtigt oder bin ich gerade in einen Randfall geraten?

Also um dies zu beantworten, tut es es nicht "gelegentlich", es tut es genau, wenn Sie es sagen, es zu tun. Das Verhalten ist absolut beabsichtigt.

Dies ist seltsam, da AFAIK ein Struktur-Subtyp normalerweise bestimmte Eigenschaften enthalten kann, solange er auch alle erforderlichen Eigenschaften seines Supertyps enthält.

Das Objekt hat diese Eigenschaft enthält, die zu 100% in Ordnung ist, aber Sie haben ausdrücklich, dass Informationen gelöscht, indem den Wert auf einen übergeordneten Typ Gießen.

+0

Das war mit Sicherheit keine meiner besten Fragen. Danke, dass du dir die Zeit genommen hast, es trotzdem zu beantworten! Die eigentliche Frage ist also, wie sich der Fluss verhält, wenn keine explizite Annotation vorhanden ist, aber der Typ muss abgeleitet werden, da ein Objekt von einer Funktion innerhalb einer komplexeren Komposition zurückgegeben wird. Gibt es auch einen Informationsverlust? Related: [Subsumption-Regel] (https://news.ycombinator.com/item?id=13047934) – ftor

+1

Ich glaube, ich würde ein explizites Beispiel brauchen, aber soweit ich weiß, sollte es keine Informationen verloren gehen Tipp Inferenz. – loganfsmyth