iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
自我挑戰組

Rayeee 的 TypeScript 的學習日記系列 第 12

<20230913> Day12. Interfaces 再探探

  • 分享至 

  • xImage
  •  

昨天簡單介紹了 interface,也舉了一個如何正確使用 interface 的情境
今天先稍微回顧一下昨天的例子

再來會記錄一下關於 interface 的其他行為

今日大綱:

  • 昨日回顧
  • 補充 interface
    • 可選屬性
    • 唯讀屬性
    • 類別實現 Class implements

昨天的範例

先來回顧一下昨天的範例

interface Attackable {
	attack(): string;
}

const godMonster = {
	name: 'godzilla',
	year: 1954,
	canFly: true,
    attack(): string {
        return `${this.name} attack!!!`
    }
}

const player1 = {
    name: 'Victor',
    hp: 100,
    skill: 'fire ball',
    attack(): string {
        return `${this.name} use ${this.skill}!!`
    }
}

const printAttack = (target: Attackable) => {
    console.log(target.attack()) 
}

printAttack(godMonster)
printAttack(player1)

在昨天的範例中,interface Attackable 制定了 可攻擊的 這個語意的介面,只要滿足他的條件,都可以被 printAttack() 方法當作合法的參數

https://ithelp.ithome.com.tw/upload/images/20230913/2016254432JYIyHOuw.png

將範例簡化一下

https://ithelp.ithome.com.tw/upload/images/20230913/20162544w8T61Xi3db.png

interface 定義的目的應該要明確,這樣才可以給非常不同的物件實作,達到重用程式碼的目的

https://ithelp.ithome.com.tw/upload/images/20230913/20162544e4fc6RlsMa.png


補充

補充的東西通常是沒有記在我原本的筆記上,在寫鐵人賽時想說要一並記錄方便給未來的自己看

  • 可選屬性
  • 唯讀屬性
  • 類別實現 Class implements (重要,先簡單提及)

可選屬性

語法:?:

在定義屬性時的冒號前面加上一個 ?,該屬性就會變成可選屬性

下面將 interface Attackable 多了一個可選的 mp 屬性
就算參數 godMonster 沒有滿足也不會報錯

interface Attackable {
    mp?: number;
    attack(): string;
}
const godMonster = {    // 怪獸物件
	name: 'godzilla',
	year: 1954,
	canFly: true,
    attack(): string {
        return `${this.name} attack!!!`
    }
}
const printAttack = (target: Attackable) => {
    console.log(target.attack()) 
}

printAttack(godMonster)

這樣的好處是可以提醒其他開發者,可能會有這個屬性傳入,並先做預先處理

const printAttack = (target: Attackable) => {
    console.log(target.attack()) 
    if (target.mp) {
        console.log(`cost mp ${target.mp} !!`)
    }
}

唯讀屬性

語法: 前綴 readonly
在定義屬性時,在屬性前綴加上 readonly,便可以將該屬性標為唯讀屬性

原本在定義物件時,滿足 interface 的物件裡面的屬性只要類別正確就好,值一樣可以再做更換,但標為唯讀屬性的話,該屬性賦值完之後值就不可以再做變動

interface Monster {
    name: string;
    hp: number;
    mp: number;
    attack(): string;
}

const motherMonster: Monster = {
    name: 'Mothra',
    hp: 300,
    mp: 1000,
    attack(): string {
        return `${this.name} attack!!`
    }
}

motherMonster.name = 'Mecha Mothra';

用了 readonly 定義屬性,那該屬性就不能再做變更

https://ithelp.ithome.com.tw/upload/images/20230913/20162544jo4n1H7vlG.png

類別實現 Class implements

Class 會用 implements 語法表示要實作的 interface,並且滿足 interface 定義的所有屬性

interface MonsterInterface {
    name: string;
    hp: number;
    mp: number;
    attack(): string;
}

class Monster implements MonsterInterface {
    name: string;
    hp: number;
    mp: number;
    attack(): string {
        return `${this.name} attack!!`
    }
    constructor(name: string, hp: number, mp: number) {
        this.name = name
        this.hp = hp;
        this.mp = mp;
    }
}

一樣,如果有缺少屬性,不滿足 interface 就會報錯

https://ithelp.ithome.com.tw/upload/images/20230913/20162544xtfEPtLCNA.png

這邊只是一個簡單的 Class 範例,如同昨天一開始所說
在 TypeScript 中,最重要的就是 Interfaces 和 Class 的協作

我們後面會開始講 Class 是什麼,但是 Class 的教學我也找了很多,完全不懂時開始看真的會覺得霧煞煞,實戰中學習才是最快能理解 Class 的方式

參考資料


上一篇
<20230912> Day11. 初探探 Interfaces
下一篇
<20230914> Day13. Class 之一
系列文
Rayeee 的 TypeScript 的學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言