# 🏅 Day 10 - Interface V.S. Type
又進入到 PK 了!這個問題也是很典型的面試考題,就趁這次機會好好跟大家來介紹吧 :D
Interface 與 Type 的寫法如下,而功能是都相同的,差別在於 type 需要用 `=` 來宣告,而 `interface` 不用。
```tsx
type Person = {
name: string,
age: number
};
interface Person {
name: string,
age: number
}
```
**Interface 與 Type 的使用時機是何時呢?**
下方我們用一張表來介紹,**`Interface`** 無法達成但 **`type`** 可以的場景:
| 功能/特性 | Interface | Type |
| --- | --- | --- |
| 可以宣告原始型別 | 否 | 是(例如 type Name = string) |
| 描述物件形狀 | 是(核心用途) | 是 |
| 擴展性 (繼承/合併) | 是(使用 extends) | 有限(可以通過交集型別 &,但不是真正的繼承) |
| 聯合型別 | 否 | 是 |
| 元組型別 | 否 | 是 |
| 映射型別 | 否 | 是 |
| 能作為函式型別 | 是(需使用函式簽名) | 是 |
## 擴展性 - 補充 Type 實現方式
在每日任務九有提及 介面擴展(Interface Extending),而 `type` 上面是沒有 extends 功能的
在 TypeScript 中,雖然 **`type`** 本身無法像 **`interface`** 那樣直接透過 **`extends`** 來進行擴充。
但可以用 **交集型別**(Intersection Types) 來達成類似的效果。
交集型別使用 **`&`** 符號來連接兩個或多個型別。例如,**`Type1 & Type2`** 會建立一個新型別,它包含了 **`Type1`** 和 **`Type2`** 的所有屬性和方法。
如果這些型別中有相同的屬性,這些屬性的型別必須兼容,否則會導致型別錯誤。
### **交集型別範例**
利用交集型別來建立一個同時包含 **`Person`** 屬性和 **`Employee`** 屬性的新型別:
```tsx=
type Person = {
name: string;
age: number;
};
type Employee = {
company: string;
department: string;
};
// 使用交集型別進行合併
type PersonEmployee = Person & Employee;
// 使用 PersonEmployee 型別
let employee: PersonEmployee = {
name: "Alice",
age: 30,
company: "Acme Corp",
department: "Engineering"
};
```
在這個範例中,**`PersonEmployee`** 型別結合了 **`Person`** 和 **`Employee`** 的屬性,因此任何符合 **`PersonEmployee`** 型別的物件都必須包含 **`name`**、**`age`**、**`company`** 和 **`department`** 這些屬性。
### interface 範例
接下來我們試著用 interface 來實現功能:
```tsx
// 定義 Person 介面
interface Person {
name: string;
age: number;
}
// 定義 Employee 介面,並擴展 Person 介面
interface Employee extends Person {
company: string;
department: string;
}
// 使用 Employee 介面
let employee: Employee = {
name: "Alice",
age: 30,
company: "Acme Corp",
department: "Engineering"
};
console.log(employee);
```
上面兩種方式都可以實現,若真的要細部來說的話:
1. **介面(`interface`)**:
- **類似於規範**:介面用於定義物件的結構,像是一份清晰的規格書
- **可擴展性**:介面可以透過 **`extends`** 擴展其他介面,有助於建立複雜的物件結構。
2. **型別別名(`type`)**:
- **不可擴展**:型別別名不支持擴展或修改,每次定義都是建立全新型別
- **對型別進行複合形式的操作**:雖然 **`type`** 不能像介面那樣透過 **`extends`** 被擴展,但它可以通過聯合(**`|`**)和交集(**`&`**)等操作組合其他型別,來建立複雜的型別。
綜上所述,才會說介面本質擁有擴展性,而 `type` 沒有。
因為 `type` 用處是在建立固定型別,只是在宣告時藉由聯合(**`|`**)和交集(**`&`**)來達成相同功能功能
## 題目:Interface V.S. Type
請消化這兩種的使用時機,可用 `hackMD`、`Notion`、`部落格` 來分享自己這道面試題:**Interface 與 Type 的使用時機是何時呢?**
### 文章推薦
1. [Interfaces vs Types in TypeScript](https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript)
2. [Day 16. 機動藍圖・介面與型別 X 混用與比較 - TypeScript Interface V.S. Type](https://ithelp.ithome.com.tw/articles/10216626)
3. [Types vs. interfaces in TypeScript](https://blog.logrocket.com/types-vs-interfaces-typescript/)
4. [Type vs Interface: Which Should You Use?](https://www.totaltypescript.com/type-vs-interface-which-should-you-use)
## 回報流程
將答案寫在 CodePen,並貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
單選題目:B、C、B、A
-->
回報區
---
| Discord | CodePen / 答案 |
|:-------------:|:----------------------------------------------------------------:|
|洧杰|[Codepen](https://codepen.io/hexschool/pen/poYgYqW?editors=1010)|
|hannahpun|[Medium](https://medium.com/hannah-lin/typescript-types-%E5%8D%81%E5%85%A8%E5%A4%A7%E8%A3%9C%E4%B8%8A-the-very-basics-f40762e0a9b9#c6ba)|
|HsienLu|[Blog](https://hsienlu.github.io/2024/01/19/TypeScript-%E4%BB%8B%E9%9D%A2-interface-vs-%E5%9E%8B%E5%88%A5%E5%88%A5%E5%90%8D-Aliases/)|
|展誠|[Codepen](https://codepen.io/hedgehogkucc/pen/BabRZzp?editors=1011)|
|hiYifang|[HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/SkhePfMKa)|
|jasperlu005|[Codepen](https://codepen.io/uzzakuyr-the-reactor/pen/GRemGbg)|
|Henry_Wu|[Codepen](https://codepen.io/hekman1122/pen/dyrWjMx?editors=1100)|
|hannahTW|[Codepen](https://codepen.io/hangineer/pen/WNmjaax?editors=1000)|
|神奇海螺|[Medium(自己的筆記)](https://medium.com/@asdfg55887/typescript-type-and-interfaec-ede3bbb7a238)|
|erwin阿瀚|[Notion](https://www.notion.so/Type-vs-Interface-ee1bc08094d642af813e91112daa2248?pvs=4)|
|rikku1756|[Codepen](https://codepen.io/rikkubook/pen/vYPmWBB?editors=1010)|
|Lisa|[Medium(自己的筆記)](https://medium.com/@lisalisa12332180/typescript-type-vs-interface-%E5%B7%AE%E7%95%B0%E8%88%87%E9%81%B8%E7%94%A8%E6%99%82%E6%A9%9F-aff7e8dd5daa)|
|77_0411|[HackMD](https://hackmd.io/@Lin77/r1z2D6DYp)|
|精靈|[Notion](https://reurl.cc/j33Nn2)|
|clairechang|[Blog](https://clairechang.tw/2024/01/23/typescript/ts-interface-vs-type/)|
|Starr|[Codepen](https://codepen.io/StarrZhong/pen/ZEPJdEL)|
|Snorlax|[HackMD](https://hackmd.io/@snorlaxpock/Sk3iGhoYp)|
|我是泇吟|[Codepen](https://codepen.io/kljuqbxs/pen/gONJBxO)|