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?
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
@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
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