我目前正在学习结构分型。我对这样的想法持怀疑态度,认为两种类型被认为是相同的,只是因为它们碰巧有一部分共同的结构。这感觉很像静态鸭子打字,它完全忽略了类型的语义层次。所以我把在普通对象的流动的结构打字定睛一看,也遇到以下行为:流的结构子类型是否“忘记”特定的子类型属性?
const o:{} = {foo: true};
o.foo; // type error
{}
是一种结构类型和所有普通对象的超类型。因此,我可以用它注释o
,因为{foo: true}
是{}
的结构子类型。但是,当我尝试访问现有的foo
属性时,此操作不会进行类型检查。这很奇怪,因为AFAIK结构子类型通常可以包含特定属性,只要它还包含其超类型的所有必需属性即可。
看起来流程的结构分型算法偶尔会忘记特定于某个子类型的属性。这种行为是有意的还是我只是遇到了边缘案例?
你能澄清你的意思吗?通过声明类型':{}',你已经明确地删除了它的类型信息,就像你做了'Animal foo = new Cat()','foo'不知道它是'Cat',它只知道它是一个'动物'。 – loganfsmyth
@loganfsmyth'{}'只是没有任何结构的最一般的普通对象类型。这当然是无用的。问题是,如果我在这个边缘案例中观察到的行为是更深层次的问题的一部分,这个问题是特定于子类型的。 – ftor
我想澄清的是,如果你认为这是一个边缘案例,那么它会是一个问题呢?在JavaScript作为一种无类型语言的情况下,绝对有些情况下你会拥有一个对象,而对它所拥有的属性一无所知。为了得到'foo',你可以这样做:if(typeof o.foo ===“boolean”){/ *用属性作为布尔值* /}来操作,它会很好用。 – loganfsmyth