---
# System prepended metadata

title: 跑完 JS30 就接著認識 TypeScript 入門｜Day09：認識介面 Interface
tags: [跑完 JS30 就接著認識 TypeScript 入門]

---

---
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
###### 文章若有任何錯誤，還請不吝給予留言指正，謝謝大家！