我目前正在學習結構分型。我對這樣的想法持懷疑態度,認爲兩種類型被認爲是相同的,只是因爲它們碰巧有一部分共同的結構。這感覺很像靜態鴨子打字,它完全忽略了類型的語義層次。所以我把在普通對象的流動的結構打字定睛一看,也遇到以下行爲:流的結構子類型是否「忘記」特定的子類型屬性?
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