轉發安全
TypeScript中的類型兼容性基於結構子類型。
結構類型是一種僅根據其成員關聯類型的方式。它正好與名義(nominal)類型造成對比。請看以下代碼:函數
interface Named { name: string; } class Person { name: string; } let p: Named; // OK, because of structural typing p = new Person();
在使用基於名義類型的語言,好比C#或Java中,這段代碼會報錯,由於Person類沒有明確說明其實現了Named接口。spa
TypeScript的結構性子類型是根據JavaScript代碼的典型寫法來設計的。 由於JavaScript裏普遍地使用匿名對象,例如函數表達式和對象字面量,因此使用結構類型系統來描述這些類型比使用名義類型系統更好。設計
TypeScript的類型系統容許某些在編譯階段沒法確認其安全性的操做。當一個類型系統具此屬性時,被當作是「不可靠」的。TypeScript容許這種不可靠行爲的發生是通過仔細考慮的。經過這篇文章,咱們會解釋何時會發生這種狀況和其有利的一面。code
TypeScript結構化類型系統的基本規則是,若是x要兼容y,那麼y至少具備與x相同的屬性。好比:對象
interface Named { name: string; } let x: Named; // y的推斷類型 is { name: string; location: string; } let y = { name: 'Alice', location: 'Seattle' }; x = y;
這裏要檢查y是否能賦值給x,編譯器檢查x中的每一個屬性,看是否能在y中也找到對應屬性。 在這個例子中, y必須包含名字是name的string類型成員。y知足條件,所以賦值正確。blog
檢查函數參數時使用相同的規則:遞歸
function greet(n: Named) { alert('Hello, ' + n.name); } greet(y); // OK
注意,y有個額外的location屬性,但這不會引起錯誤。 只有目標類型(這裏是 Named)的成員會被一一檢查是否兼容。接口
這個比較過程是遞歸進行的,檢查每一個成員及子成員。ip