2016-12-30 99 views
3

下面是一個簡單的程序:爲什麼打字稿在界面中使用自定義符號有限制?

const mySymbol = Symbol(); 
interface Fails { 
    [mySymbol]: boolean; 
} 

interface Succeeds { 
    [Symbol.hasInstance]: boolean; 
} 

這裏是從compling輸出:

$ tsc --lib es6 odd.ts 
odd.ts(3,3): error TS1169: A computed property name in an interface must directly refer to a built-in symbol. 

錯誤是可以理解的,只有內置的符號可以作爲打字稿接口的屬性類型,但這似乎是一個任意的限制。

有人可以解釋爲什麼這個限制存在嗎?

回答

3

考慮一些代碼:

// Implementation not visible to us 
declare function getSymbol(): Symbol; 

const s1 = getSymbol(); 
const s2 = getSymbol(); 

interface Type1 { 
    [s1]: string; 
    [s2]: number; 
} 

這是聲明是否合法?讓我們問一些朋友。

愛麗絲,因爲getSymbol每次它調用時返回不同的符號,所以s1s2創建兩個單獨的屬性插槽。

鮑勃沒有,因爲getSymbol總是會在每次調用時返回相同的符號,所以s1s2是同一屬性的衝突的聲明。

前夕哈哈哈,因爲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; 
} 

也許getSymbol1getSymbol2返回相同的符號。也許他們沒有。也許他們有時會。誰知道?如果沒有明確地命名個別符號實例的方法,這是一個無法解決的難題。但是類型系統,特別是結構類型,在描述實例標識時很不好。您可以在某個系統中爲每個符號實例命名,但是您仍然無法描述每次調用時都會返回一個新符號的函數。總的來說,對於類似第一個代碼片段的代碼來說,將會非常困難,因爲類型系統將假定被調用兩次的同一個函數會生成兩個實際上完全相同的對象。

+0

謝謝!非常有意義。 –

+0

儘管如此,像hasInstance這樣的衆所周知的符號只是編譯器已知的。我想這是假設沒有有趣的事情發生在他們被重新分配的地方。 –

+0

正確 - 在這方面,「符號」對象的聲明成員被假定爲「正常」 –

相關問題