考慮一些代碼:
// Implementation not visible to us
declare function getSymbol(): Symbol;
const s1 = getSymbol();
const s2 = getSymbol();
interface Type1 {
[s1]: string;
[s2]: number;
}
這是聲明是否合法?讓我們問一些朋友。
愛麗絲說是,因爲getSymbol
每次它調用時返回不同的符號,所以s1
和s2
創建兩個單獨的屬性插槽。
鮑勃說沒有,因爲getSymbol
總是會在每次調用時返回相同的符號,所以s1
和s2
是同一屬性的衝突的聲明。
前夕說哈哈哈,因爲getSymbol
隨機返回兩個不同的標誌之一,所以誰知道是怎麼回事。
誰是對的?我不知道。沒人做到。我們都只是在猜測,因爲我們看不到getSymbol
的實施。即使我們可以,它的實施可能是任意複雜的。
而且,即使我們能描述getSymbol
的行爲,我們仍然不能解釋這種代碼:
// Implementations not visible to us
declare function getSymbol1(): Symbol;
declare function getSymbol2(): Symbol;
const s1 = getSymbol1();
const s2 = getSymbol2();
interface Type1 {
[s1]: string;
[s2]: number;
}
也許getSymbol1
和getSymbol2
返回相同的符號。也許他們沒有。也許他們有時會。誰知道?如果沒有明確地命名個別符號實例的方法,這是一個無法解決的難題。但是類型系統,特別是結構類型,在描述實例標識時很不好。您可以在某個系統中爲每個符號實例命名,但是您仍然無法描述每次調用時都會返回一個新符號的函數。總的來說,對於類似第一個代碼片段的代碼來說,將會非常困難,因爲類型系統將假定被調用兩次的同一個函數會生成兩個實際上完全相同的對象。
謝謝!非常有意義。 –
儘管如此,像hasInstance這樣的衆所周知的符號只是編譯器已知的。我想這是假設沒有有趣的事情發生在他們被重新分配的地方。 –
正確 - 在這方面,「符號」對象的聲明成員被假定爲「正常」 –