--- GA: G-7BSJTG7RYN --- 我們在 [<Day04:型別系統 - 明文型別 Literal Types 與 型別化名>](https://hackmd.io/@elzuoc/rkcMxJJx3) 聊過 [型別化名](https://hackmd.io/@elzuoc/rkcMxJJx3#%E5%9E%8B%E5%88%A5%E5%8C%96%E5%90%8D-Type-Alias)。 > 型別化名:主要的功用在於 **簡化程式碼** 及 **抽象化型別(Type Abstraction)**。 而 **介面** 宣告,與型別化名的功用相同,是另一種 **抽象化** 物件型別的方法。 來看個簡單的範例: ```typescript= interface Rectangle { width: number; height: number; } ``` 使用方式與型別化名相同,來看一個型別註記的範例: > 若忘記 `Arrow Function` 如何註記,趕快複習 [型別註記(Type Annotation)](https://hackmd.io/@elzuoc/H1eItEny2#%E5%9E%8B%E5%88%A5%E8%A8%BB%E8%A8%98%E5%9B%9B%EF%BC%9A%E8%A8%BB%E8%A8%98%E5%9C%A8-Arrow-Function-%E5%AE%A3%E5%91%8A%E6%99%82)唷! ```typescript= const verifySquare: (size: Rectangle) => boolean = (size) => size.width === size.height; const isSquare: boolean = verifySquare({ width: 100, height: 100 }) console.log( isSquare ); // true ``` --- 2023/04/06 Update ### 介面擴展(Interface Extension / Interface Inheritance) 在這裡我們會使用到 `extends` 這個關鍵字,之後我們在 `class` 的章節也會談到,雖然都有擴展和繼承之意,不過內容用法完全不同。 來看個例子,我們透過 `interface` 先定義兩個與會員有關的 `Object Literal`: ```typescript= enum Gender { Male, Female, Other}; interface MemberAccount { email: string; password: string; } interface MemberInfo { nickname?: string; birth?: Date; gender?: Gender; } ``` 接著我們再定義一個 `interface` - `Member`,這個 `Member` 我們從 `MemberAccount` 和 `MemberInfo` 擴展而來: ```typescript= interface Member extends MemberAccount, MemberInfo {}; ``` 這時,被宣告為 `Member` 型別的物件屬性,有幾項特徵: 1. 必須要有 `MemberAccount` 及 `MemberInfo` 的所有非選用屬性。 2. 選用屬性若不需要,可省略不寫。 3. 不可加入不存在於 `MemberAccount` 及 `MemberInfo` 的屬性 也就是 **少非選用屬性** 或 **多一個新屬性**,都會錯誤。 ```typescript= let RogerInfo: Member = { email: 'roger@example.com', password: '***', nickname: 'Roger', birth: new Date(1991,1,1), exist: false, // error // gender: Gender.Female } ``` 在這個範例中,非選用屬性 `email`, `password` 都一定要用到。 不過用來擴展的物件並無 `exist` 這個屬性,所以此處會造成錯誤。最後 `gerder` 由於是選用屬性,若用不到可省略。 其實我們在 [<Day06:型別系統 - 複合型別 Composite Types>](https://hackmd.io/@elzuoc/rJRtRjUx3) 中的 [交集型別](https://hackmd.io/@elzuoc/rJRtRjUx3#%E4%BA%A4%E9%9B%86%E5%9E%8B%E5%88%A5-Intersection-Type) 有提過類似的概念。 不過用這種延展的方式,意義上比較趨於想要定義屬性與功能,對比於使用交集的方式定義物件屬性的方式來看,延展的特性還是使用 `interface`,可讀性會比用 `type` 定義來的更好。([相關文章:介面 Interface V.S. 型別 Type](https://ithelp.ithome.com.tw/articles/10215586)) --- ### Reference - [TypeScript Official Site - Interfaces](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#interfaces) --- > 系列:[`跑完 JS30 就接著認識 TypeScript 入門`](https://hackmd.io/@elzuoc?tags=%5B%22%E8%B7%91%E5%AE%8C+JS30+%E5%B0%B1%E6%8E%A5%E8%91%97%E8%AA%8D%E8%AD%98+TypeScript+%E5%85%A5%E9%96%80%22%5D) > 上一篇:[Day08:型別系統 - 索引型別 Indexable Types](https://hackmd.io/@elzuoc/Hyf-oGue2) > 下一篇:[Day10:認識類別(Class)](https://hackmd.io/@elzuoc/HkSlRVueh) ###### tags: [`跑完 JS30 就接著認識 TypeScript 入門`](https://hackmd.io/@elzuoc?tags=%5B%22%E8%B7%91%E5%AE%8C+JS30+%E5%B0%B1%E6%8E%A5%E8%91%97%E8%AA%8D%E8%AD%98+TypeScript+%E5%85%A5%E9%96%80%22%5D) ###### Created on ∥ March 22, 2023 ###### 文章若有任何錯誤,還請不吝給予留言指正,謝謝大家!