В настоящее время я изучаю структурную типизацию. Я скептически отношусь к идее, что два типа считаются эквивалентными только потому, что у них есть часть общей структуры. Это очень похоже на статическую утиную типизацию и полностью игнорирует семантический уровень типов. Поэтому я внимательно изучил структурную типизацию обычных объектов потоком и столкнулся со следующим поведением:
const o:{} = {foo: true};
o.foo; // type error
{}
— это структурный тип и надтип всех обычных объектов. Следовательно, имеет смысл аннотировать им o
, потому что {foo: true}
является структурным подтипом {}
. Однако, когда я пытаюсь получить доступ к существующему свойству foo
, эта операция не выполняет проверку. Это странно, потому что AFAIK структурный подтип обычно может содержать определенные свойства, если он также включает все необходимые свойства своего супертипа.
Кажется, что алгоритм структурного подтипа потока иногда забывает свойства, характерные для определенного подтипа. Это поведение предназначено, или я просто столкнулся с крайним случаем?
: {}
, вы явно стерли информацию о нем, точно так же, как если бы вы сделалиAnimal foo = new Cat()
,foo
не знает, что этоCat
, он просто знает, что этоAnimal
. - person loganfsmyth   schedule 13.09.2017{}
- это просто самый общий обычный тип объекта без какой-либо структуры. Конечно, это довольно бесполезно. Вопрос в том, является ли поведение, которое я наблюдал в этом пограничном случае, частью более глубокой проблемы, характерной для подтипирования. - person   schedule 14.09.2017foo
, вы можете сделатьif(typeof o.foo === "boolean") { /* do stuff with the property as a boolean */ }
, и все будет отлично. - person loganfsmyth   schedule 14.09.2017{}
— это объект с неизвестными свойствами, которые могут быть полезны, тогда как{||}
— это объект без свойств, что довольно бесполезно. - person loganfsmyth   schedule 14.09.2017{}
как объект без или с неизвестными реквизитами. Вот еще пример:type O = {foo: boolean}; const o:O = {foo: true, bar: 123};
. Это работает, потому что типo
является структурным подтипомO
. Теперь, когда я пытаюсь получить доступ кo.bar
, свойству, специфичному для подтипа, я получаю ошибку типа. Это не кажется правильным. - person   schedule 14.09.2017o
— это объект со свойствамиfoo
иbar
, но поскольку вы привели его к супертипуO
, система типов больше не знает, что у него есть свойствоbar
. Это тот же тип сбоя, который вы видите в чем-то вроде ideone.com/i9SjfW. Как только вы сказали системе типов, что этоO
, это все, что она знает. Да, у объекта есть и другие свойства, но вы явно сказали системе типов забыть об их наличии. Структурные типы Flow — это то, что позволяет вам приводить их, но вы столкнетесь с той же проблемой и с иерархией классов, если приведете к супертипу. - person loganfsmyth   schedule 14.09.2017