又進入到 PK 了!這個問題也是很典型的面試考題,就趁這次機會好好跟大家來介紹吧 :D
Interface 與 Type 的寫法如下,而功能是都相同的,差別在於 type 需要用 =
來宣告,而 interface
不用。
type Person = {
name: string,
age: number
};
interface Person {
name: string,
age: number
}
Interface 與 Type 的使用時機是何時呢?
下方我們用一張表來介紹,Interface
無法達成但 type
可以的場景:
功能/特性 | Interface | Type |
---|---|---|
可以宣告原始型別 | 否 | 是(例如 type Name = string) |
描述物件形狀 | 是(核心用途) | 是 |
擴展性 (繼承/合併) | 是(使用 extends) | 有限(可以通過交集型別 &,但不是真正的繼承) |
聯合型別 | 否 | 是 |
元組型別 | 否 | 是 |
映射型別 | 否 | 是 |
能作為函式型別 | 是(需使用函式簽名) | 是 |
在每日任務九有提及 介面擴展(Interface Extending),而 type
上面是沒有 extends 功能的
在 TypeScript 中,雖然 type
本身無法像 interface
那樣直接透過 extends
來進行擴充。
但可以用 交集型別(Intersection Types) 來達成類似的效果。
交集型別使用 &
符號來連接兩個或多個型別。例如,Type1 & Type2
會建立一個新型別,它包含了 Type1
和 Type2
的所有屬性和方法。
如果這些型別中有相同的屬性,這些屬性的型別必須兼容,否則會導致型別錯誤。
利用交集型別來建立一個同時包含 Person
屬性和 Employee
屬性的新型別:
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 來實現功能:
// 定義 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);
上面兩種方式都可以實現,若真的要細部來說的話:
介面(interface
):
extends
擴展其他介面,有助於建立複雜的物件結構。型別別名(type
):
type
不能像介面那樣透過 extends
被擴展,但它可以通過聯合(|
)和交集(&
)等操作組合其他型別,來建立複雜的型別。綜上所述,才會說介面本質擁有擴展性,而 type
沒有。
因為 type
用處是在建立固定型別,只是在宣告時藉由聯合(|
)和交集(&
)來達成相同功能功能
請消化這兩種的使用時機,可用 hackMD
、Notion
、部落格
來分享自己這道面試題:Interface 與 Type 的使用時機是何時呢?
將答案寫在 CodePen,並貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)
Discord | CodePen / 答案 |
---|---|
洧杰 | Codepen |
hannahpun | Medium |
HsienLu | Blog |
展誠 | Codepen |
hiYifang | HackMD |
jasperlu005 | Codepen |
Henry_Wu | Codepen |
hannahTW | Codepen |
神奇海螺 | Medium(自己的筆記) |
erwin阿瀚 | Notion |
rikku1756 | Codepen |
Lisa | Medium(自己的筆記) |
77_0411 | HackMD |
精靈 | Notion |
clairechang | Blog |
Starr | Codepen |
Snorlax | HackMD |
我是泇吟 | Codepen |