TypeScript Type Compatibility 类型兼容性
官方鏈接
TypeScript 中的類型兼容性基于結構子類型。 結構類型是一種僅基于其成員關聯類型的方法。這與 nominal typing 相反。考慮以下代碼:
interface Pet {name: string; } class Dog {name: string; } let pet: Pet; // OK, because of structural typing pet = new Dog();如果是 Java 或者 ABAP 編程語言,上述代碼會出現編譯錯誤,因為 Pet 類型 和 Dog 類型沒有任何關聯,雖然其正好都有一個類型為 string 的 name 字段。
在 C# 或 Java 等名義類型的語言中,上述代碼將是錯誤的,因為 Dog 類沒有明確地將自己描述為 Pet 接口的實現者。
TypeScript 的結構類型系統是根據 JavaScript 代碼的典型編寫方式設計的。 因為 JavaScript 廣泛使用匿名對象,如函數表達式和對象字面量,所以用結構類型系統而不是名義類型系統來表示 JavaScript 庫中發現的各種關系要自然得多。
什么是健全性 Soundness
TypeScript 的類型系統允許某些在編譯時無法知道的操作是安全的。 當一個類型系統具有這個屬性時,它就被認為不是“健全的”。 仔細考慮了 TypeScript 允許不良行為的地方,在整個文檔中,我們將解釋這些地方發生的地方以及它們背后的激勵場景。
TypeScript 結構類型系統的基本規則是,如果 y 至少具有與 x 相同的成員,則 x 與 y 兼容。 例如,考慮以下代碼,其中包含一個名為 Pet 的接口,該接口具有 name 屬性。這段代碼是合法的:
interface Pet {name: string; } let pet: Pet; // dog's inferred type is { name: string; owner: string; } let dog = { name: "Lassie", owner: "Rudd Weatherwax" }; pet = dog;為了檢查 dog 是否可以分配給 pet,編譯器會檢查 pet 的每個屬性,以在 dog 中找到對應的兼容屬性。 在這種情況下, dog 必須有一個名為 name 的成員,它是一個字符串。 確實如此,因此允許分配。
同理,下列代碼也合法:
interface Pet {name: string; } let dog = { name: "Lassie", owner: "Rudd Weatherwax" }; function greet(pet: Pet) {console.log("Hello, " + pet.name); } greet(dog); // OK請注意 dog 有一個額外的 owner 屬性,但這不會產生錯誤。 檢查兼容性時只考慮目標類型的成員(在本例中為 Pet)。
如何判斷兩個函數類型是否兼容
雖然比較原始類型和對象類型相對簡單,但哪些類型的函數應該被視為兼容的問題更復雜一些。 讓我們從兩個僅參數列表不同的函數的基本示例開始:
let x = (a: number) => 0; let y = (b: number, s: string) => 0; y = x; // OK x = y; // Error要檢查 x 是否可分配給 y,我們首先查看參數列表。 x 中的每個參數都必須在 y 中有一個對應類型的兼容參數。 請注意,不考慮參數的名稱,只考慮它們的類型。 在這種情況下,x 的每個參數在 y 中都有一個對應的兼容參數,因此允許賦值。
第二個賦值是錯誤的,因為 y 有一個 x 沒有的必需的第二個參數,所以不允許賦值。
您可能想知道為什么我們允許像示例 y = x 中那樣“丟棄”參數。 允許這種賦值的原因是忽略額外的函數參數在 JavaScript 中實際上很常見。 例如,Array#forEach 為回調函數提供了三個參數:數組元素、其索引和包含的數組。 盡管如此,提供一個只使用第一個參數的回調是非常有用的:
let items = [1, 2, 3]; // Don't force these extra parameters items.forEach((item, index, array) => console.log(item)); // Should be OK! items.forEach((item) => console.log(item));再來看如果兩個函數的返回類型不完全一致,兼容性又將如何處理。
let x = () => ({ name: "Alice" }); let y = () => ({ name: "Alice", location: "Seattle" }); x = y; // OK y = x; // Error, because x() lacks a location propertyFunction Parameter Bivariance
總結
以上是生活随笔為你收集整理的TypeScript Type Compatibility 类型兼容性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 空间计量的基本模型学习笔记
- 下一篇: s12巨魔大乱斗出什么装备 2022巨魔