J'étudie actuellement le typage structurel. Je suis sceptique quant à l'idée que deux types sont considérés comme équivalents simplement parce qu'ils ont une partie de leur structure en commun. Cela ressemble beaucoup à un typage de canard statique et il ignore complètement le niveau sémantique des types. Alors j'ai regardé de plus près la saisie structurelle de flux d'objets ordinaires et ont rencontré le comportement suivant:Est-ce que le sous-typage structurel du flux "oublie" des propriétés de sous-types spécifiques?
const o:{} = {foo: true};
o.foo; // type error
{}
est un type de structure et supertype de tous les objets ordinaires. Par conséquent, il est logique que je puisse annoter o
avec lui, car {foo: true}
est un sous-type structurel de {}
. Toutefois, lorsque j'essaie d'accéder à la propriété foo
existante, cette opération ne vérifie pas de type. Ceci est étrange car AFAIK un sous-type structurel peut généralement contenir des propriétés spécifiques tant qu'il inclut également toutes les propriétés requises de son supertype.
Il semble que l'algorithme de sous-typage structurel de flux oublie parfois des propriétés spécifiques à un certain sous-type. Est-ce que ce comportement est prévu ou est-ce que je viens juste de tomber dans un cas limite?
Pourriez-vous préciser ce que vous voulez dire? En déclarant le type ': {}', vous avez explicitement effacé les informations de type à ce sujet, comme si vous aviez 'Animal foo = new Cat()', 'foo' ne sait pas que c'est un' Cat', sait juste que c'est un 'Animal'. – loganfsmyth
@loganfsmyth '{}' est juste le type d'objet ordinaire le plus général sans aucune structure. C'est assez inutile bien sûr.La question est de savoir si le comportement que j'ai observé avec ce cas limite fait partie d'un problème plus profond, qui est spécifique au sous-typage. – ftor
Ce que j'essaie de clarifier est, qu'en est-il de ce que vous voyez un cas d'un bord, et qu'en serait-il un problème? Dans le cas de JavaScript en tant que langage non typé, il y a absolument des cas où vous aurez un objet et ne connaîtrez rien sur les propriétés dont il dispose. Pour obtenir 'foo', vous pouvez faire' if (typeof o.foo === "booléen") {/ * faire des choses avec la propriété comme un booléen * /} 'et ça marchera très bien. – loganfsmyth