TypeScript - Interfaces

TypeScript - Interfaces

Interfaces + Classes = TS 提高程式碼複用性。
這一篇主要是介紹與了解 Interfaces 的作用,並會在下一篇文章介紹 Classes 與兩者併用的技巧與好處。

Interfaces

Interfaces 為物件定義一個新的型別,來描述其屬性名稱與值。
在不使用 Interface 以前,我們要用型別註釋來定義物件參數型別,都會寫得很長。但使用 Interfaces 就可以有效解決這個問題。

使用 Interface 來定義物件內的參數型別,就可以直接使用。在以下範例中,只要傳入的內容有符合 Article 所定義的參數與型別即可,不需要依序傳入也沒關係。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Article {
name: string;
page: number;
read: boolean;
}
const articleContent = {
name: 'learn',
page: 3,
read: true
}
const learnTypeScript = (blog: Article): void => {
console.log(blog.name);
}
learnTypeScript(articleContent)

函式中,可以傳入 Interface 中沒有定義的變數,但若是沒有傳入必要的參數與型別,則會出現錯誤,例如:(以下範例的 articleContent 少了 read 參數)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Article {
name: string;
page: number;
read: boolean;
}

const articleContent = {
name: 'learn',
page: 3,
}

const learnTypeScript = (blog: Article): void => {
console.log(blog.name);
}
learnTypeScript(articleContent) // 錯誤
// Argument of type '{ name: string; page: number; }' is not assignable to parameter of type 'Article'.
// Property 'read' is missing in type '{ name: string; page: number; }' but required in type 'Article'.(2345)

鋪梗完後,接下來就要介紹 Interfaces 的 Optional Properties (可選屬性)

可選屬性 (Optional Properties)

可選屬性可以透過屬性後面加上『?』 來讓參數變成選填。
與上面出現錯的範例相同,這邊把 interface 中的 read 後面加上 ? :

1
2
3
4
5
interface Article {
name: string;
page: number;
read?: boolean;
}

再次執行就會發現錯誤消失了,可選屬性可用在定義可有可無的參數上。

另外,Interface 也有提供唯讀屬性:

唯讀屬性(readonly properties)

唯讀屬性和 const 定義變數時很像,只能讀取,不能修改變數的值。
在 Interface 定義屬性前加上 readonly,就可以讓這個屬性無法被修改

1
2
3
4
interface Article {
readonly name: string;
readonly page: number;
}

小補充:const 和 readonly 的差異,在於 const 是針對變數,readonly 則是屬性

了解 Interface 的作用後,回到使用它的核心,也就是要提高程式碼的複用性,因此最後來了解一下 Interface 與函式的結合,寫出提升複用性的程式碼:

Interface 中定義 function

在 Interface 中也可以定義 function,例如範例中的 getPage():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface Article {
name: string;
page: number;
read?: boolean;
getPage() : string;
}

const articleContent = {
name: 'learn',
page: 3,
getPage(): string {
return `Page: ${this.page} 篇`
}
}

const learnTypeScript = (blog: Article): void => {
console.log(blog.getPage());
}

使用 Interface 提高複用性

使用一個 Interface 定義 function,並確認函式回傳為 string,當傳入的函式為完全不同的物件(articleContent, newsContent)也是 ok 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Page {
getPage() : string;
}

const getPage = (post: Page): void => {
console.log(post.getPage());
}

const articleContent = {
name: 'learn',
page: 3,
getPage(): string {
return `Page: ${this.page} 篇`
}
}

const newsContent = {
name: 'Banana 新聞',
day: 21,
getPage(): string {
return `${this.day} 天的新聞`
}
}
getPage(articleContent)
getPage(newsContent)

以上的範例程式碼都可以貼到 TypeScript Playground 來運行看看哦~

參考資料:
TypeScript - Interfaces
Udemy - Typescript: The Complete Developer’s Guide 2020

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×