Deno 入門指南
  • 前言
  • Deno 更新日誌
  • 簡介
    • Deno 跟 Node.js 的主要差異
    • Hello, World!
  • TypeScript 基礎篇
    • 變數宣告
    • 使用型別系統
    • 流程判斷與迴圈
    • 函式宣告
    • This 與 Arrow Function
    • 在函式中應用強型別
    • 介面
    • 型別別名
    • 物件導向概念
    • 類別的封裝與繼承
    • 介面與類別、抽象類別
    • 泛型的概念與實作
    • 型別補充
  • Deno CLI
    • 快速開始
    • 沙盒機制
    • URL Import
    • 編譯選項
    • 相關工具及測試
      • WebGPU API
      • Deno.resolveDns
      • 程式碼編譯器
      • 程式碼檢查器
      • 依賴檢查器
      • 文件產生器
      • 程式碼打包工具
      • 腳本安裝
      • 程式碼格式化
      • Deno 命名空間與編譯器 API
      • 使用 Deno 進行測試
  • 使用 Deno 打造多線程應用
    • 多線程概念
    • Deno Workers
    • 使用多線程計算矩陣相乘
  • 使用 Deno 打造 Web API
    • Web API 介紹
    • Oak 框架介紹
    • 使用 Denon 精簡指令
    • 實作 Web API
    • MongoDB 安裝教學
    • Deno 與 MongoDB 共舞
    • 完成第一支 Web API
    • 淺談跨來源資源共用(CORS)與解決辦法
Powered by GitBook
On this page
  • 介面實戰
  • 補充:唯讀屬性
  • 延伸閱讀

Was this helpful?

  1. TypeScript 基礎篇

介面

Previous在函式中應用強型別Next型別別名

Last updated 4 years ago

Was this helpful?

提供給軟體元件間的介面會被存取到的事物的種類可以包括:、、的種類、規格、。在某些個案,定義作為介面的一部份可能會很有用。介面常會透過註解或(於某些實驗性語言)透過正式的邏輯斷言指明那些程式和方法的功能。

--

如果你是一名使用過物件導向語言做開發的開發者,肯定對 Interface 不陌生。

Interface 可以讓我們先對物件規定好範疇,再進行實作。

以 PHP 為例,若我們今天想要實作一個 Linked List :

interface linkedListInterface{
    function printList();
    function pushFront($data);
    function delete($inputValue);
    function pushBack($data);
    function reverse();
    function clearList();
}
class linkedList implements linkedListInterface{
// 實作...
}

上述程式碼中,我們先定義好了一個資料結構中有的抽象方法,再使用 class 進行實作。

  • 知識點:

或許有人會覺得先定義好再做實作很多此一舉,但是當今天有多人開發的需求, Interface 就是一個相當好用的工具,因為先定義好了相關屬性和方法,可以有效避免多人開發的衝突。

介面實戰

而在 TypeScript 中,我們同樣可以介面來定義物件的型別,至於到底該如何使用介面,就讓我們一起看看以下範例吧!

每個人都有姓名跟年齡, ian 也是人,所以在用物件定義 ian 之前,我們可以把這些確定的事物給抽離出來:

interface Person {
    name: string;
    age: number;
}

定義好一個人必備的元素後,實作物件 ian 時,我們就可以遵尋定義好的介面 Person :

let ian: Person = {
    name: 'Ian',
    age: 21
};

需要注意的是,在遵循介面實作物件時,不能有多餘或是缺少的屬性,像是:

let ian: Person = {
    name: 'Ian',
    age: 21,
  	birthday: 19990119
};

或是:

let ian: Person = {
    name: 'Ian',
};

如果讀者認為某些屬性就算沒有被實作出來也沒關係,也可以考慮使用可選屬性: ? :

interface Person {
    name: string;
    age?: number;
}

如此一來,不實作 age 也沒關係啦!

let peter: Person = {
    name: 'Peter',
};

假設讀者們更難搞,希望實作物件時可以有預期之外的屬性出現,那我們可以使用任意屬性:

interface Person {
    name: string;
    age?: number;
    [propName: string]: string;
}

注意,若定義了任意屬性,那麼確定屬性和可選屬性的型別都必須是它的型別的子集。

什麼意思呢?

我們透過歸類可以知道:

  1. name 的型別是 string。

  2. age 的型別是 number。

所以,任意屬性的型別至少必須是 string 和 number 的聯集:

interface Person {
    name: string;
    age?: number;
    [propName: string]: string | number;
}

更懶一點的作法,可以讓任意屬性的型別指定為 any 。

不過筆者不建議這麼做就是了。

interface Person {
    name: string;
    age?: number;
    [propName: string]: string | number;
}

補充:唯讀屬性

若今天讀者在實作物件時,希望該物件的特定屬性在物件初始化以後就不能重新進行賦值,可以使用唯獨屬性: readonly 。

interface Person {
    readonly name: string;
    age?: number;
    [propName: string]: string | number;
}

不過在現實世界中這樣做的話,應該會有人感到痛不欲生吧,像是:

而最好的作法應該是這樣:

interface Female {
    name: string;
    readonly age?: number;
}
let cindy: Female = {
    name: 'Cindy',
  	age: 18
};

延伸閱讀

同樣的事情在不同人眼中可能會有不同的見解、看法。

在讀完本篇以後,筆者也強烈建議大家去看看以下文章,或許會對型別、變數宣告...等觀念有更深層的看法唷!

    如果讀者希望看到繁體中文的相關資料,我認為這系列真的必看,講的非常詳細。

    筆者在這 30 天中很難將 TypeScript 的各項觀念一一帶出,如果有需要繼續向下探索,

    真的大推、怒推這個系列文。

知識點:

常數
資料型別
程式
例外
型別簽名
變數
wikipedia
資料結構
Linked List
黃宏成台灣阿成世界偉人財神總統
讓 TypeScript 成為你全端開發的 ACE!
Day 11. 前線維護・特殊型別 X 無法無天 - Any & Unknown Type
Day 12. 機動藍圖・介面宣告 X 使用介面 - TypeScript Interface Intro.