---
# System prepended metadata

title: "\U0001F3C5 Day 6 - 列舉型別（Enum）"
tags: [TypeScript 30 天證書培訓營 - 2024]

---

# 🏅 Day 6 - 列舉型別（Enum）

列舉（Enum）型別用於取值，在 C# / C / JAVA 常見到它的身影，而本身 JavaScript 是沒此語言特性的。

**列舉適合被限制在一定範圍內的場景**，例如一週只能有七天，紅綠燈有紅、綠、黃的狀態。

```tsx=
enum Weekday {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

// 使用列舉
console.log(Weekday.Monday);
// 印出 1
```

為何顯示為 1 呢？這是因為列舉成員被初始化時，會從 0 開始按順序賦予遞增的數值，而且還會實現從列舉的值到其名稱的反向映射。

```tsx=
enum Weekday {
    Sunday,    // 賦值為 0
    Monday,    // 賦值為 1
    Tuesday,   // 賦值為 2
    Wednesday, // 賦值為 3
    Thursday,  // 賦值為 4
    Friday,    // 賦值為 5
    Saturday   // 賦值為 6
}

// 範例一：使用數字來取得對應的列舉名
let dayName = Weekday[2];  // dayName 值為 "Tuesday"
// 範例二，顯示今天禮拜幾
let today = Weekday.Monday; // today 值為 1

```

這段輸出 JavaScript 的話，會變成如下，好讓 JavaScript 也擁有列舉功能

```tsx=
"use strict";
var Weekday;
(function (Weekday) {
    Weekday[Weekday["Sunday"] = 0] = "Sunday";
    Weekday[Weekday["Monday"] = 1] = "Monday";
    Weekday[Weekday["Tuesday"] = 2] = "Tuesday";
    Weekday[Weekday["Wednesday"] = 3] = "Wednesday";
    Weekday[Weekday["Thursday"] = 4] = "Thursday";
    Weekday[Weekday["Friday"] = 5] = "Friday";
    Weekday[Weekday["Saturday"] = 6] = "Saturday"; // 賦值為 6
})(Weekday || (Weekday = {}));
// 範例一：使用數字來取得對應的列舉名
let dayName = Weekday[2]; // dayName 值為 "Tuesday"
// 範例二，顯示今天禮拜幾
let today = Weekday.Monday; // today 值為 1
```

## enum 手動賦值

除此之外 enum 也可以賦值為其它型別，方便開發者運用

```tsx=
enum Weekday {
    Sunday = "Sun",
    Monday = "Mon",
    Tuesday = "Tue",
    Wednesday = "Wed",
    Thursday = "Thu",
    Friday = "Fri",
    Saturday = "Sat"
}

// 範例一：使用列舉名來取得對應的字串簡寫
let dayName = Weekday.Tuesday;  // dayName 值為 "Tue"

// 範例二：顯示今天星期幾（以簡寫形式）
let today = Weekday.Monday; // today 值為 "Mon"
```

## 範例：紅綠燈

像是紅綠燈它就是屬於狀態限制在一定範圍，也就是只有紅綠黃色，就相當適合使用 enum 來定義。

### 沒使用 enum 的話

在我們寫程式時，通常會用數字來代表不同的狀態。在技術上雖然可行，缺點就是可讀性很差，當其它同事接手你的程式碼時，需要知道每個數字代表的意思，就變得不好理解。

也不要說同事，可能過一週，你自己也看不懂這些數字的意涵了，如下程式碼範例：

```tsx=
// 定義紅綠燈狀態的數字
const RED = 0;
const YELLOW = 1;
const GREEN = 2;

// 當前紅綠燈狀態
let currentLight = RED;

// 檢查紅綠燈狀態
function checkTrafficLight(status: number) {
    if (status === RED) {
        console.log("紅燈，請停止！");
    } else if (status === YELLOW) {
        console.log("黃燈，請注意！");
    } else if (status === GREEN) {
        console.log("綠燈，可以行駛！");
    } else {
        console.log("未知燈號！");
    }
}

// 檢查當前燈號
checkTrafficLight(currentLight);
```

### 有用 enum 範例

編號完全消失不見，另外藉由參數上的型別註釋，可讀性與維護性也大為提升：

```tsx=
enum TrafficLight {
    Red,    // 紅燈
    Yellow, // 黃燈
    Green   // 綠燈
}

// 當前紅綠燈狀態
let currentLight = TrafficLight.Red;

// 檢查紅綠燈狀態
function checkTrafficLight(status: TrafficLight) {
    switch (status) {
        case TrafficLight.Red:
            console.log("紅燈，請停止！");
            break;
        case TrafficLight.Yellow:
            console.log("黃燈，請注意！");
            break;
        case TrafficLight.Green:
            console.log("綠燈，可以行駛！");
            break;
        default:
            console.log("未知燈號！");
    }
}

// 檢查當前燈號
checkTrafficLight(currentLight);
```

## 待辦事項範例程式碼

```tsx=
enum TodoStatus {
    Pending,    // 待辦事項尚未開始
    InProgress, // 待辦事項正在進行中
    Completed,  // 待辦事項已完成
    Cancelled   // 待辦事項被取消
}

// 待辦事項陣列
let todos = [];

// 新增待辦事項的函數
function addTodoItem(name: string) {
    const newTodo = {
        name: name,
        status: TodoStatus.Pending // 新增的待辦事項默認狀態為 "Pending"
    };
    todos.push(newTodo);
    console.log(`新增待辦事項: "${name}"`);
}

// 範例：新增一個待辦事項
addTodoItem("完成 TypeScript 專案");

// 顯示目前所有待辦事項
console.log(todos);
```

## 列舉、元組、陣列

蠻多開發者比較難判斷何時用這三種資料結構，以下摘要分享：

| 特性/用途 | 列舉 (Enum) | 元組 (Tuple) | 陣列 (Array) |
| --- | --- | --- | --- |
| 用途定義 | 表示一組相關的資料集合，如狀態或選項。 | 儲存固定數量、固定順序的多種型別的值。 | 儲存多個相同型別的值。 |
| 索引方式 | 通過名稱或數值索引。 | 通過位置索引。 | 通過位置索引。 |
| 語義清晰性 | 高（每個值都有明確的名稱）。 | 中（位置重要，但型別可以變）。 | 低（因會儲存多資料內容）。 |
| 例子 | enum Color { Red, Green, Blue } | let point: [number, number] = [7, 5];  | let numbers: number[] = [1, 2, 3]; |
| 應用場景 | 固定的選項（如天數、狀態）。 | 當需要固定組合的不同型別值時（如座標、excel 欄）。 | 儲存一系列相同型別的元素（例如數據列表）。 |

### 使用情境：

1. 如果你需要表示一組固定的選項，如天數、方向、狀態，可以使用 **列舉** **`enum`**。
2. 假使你需要存儲固定長度的多種類型的數據（如座標、excel 欄），可以使用**元組**。
3. 需要儲存大量相同型別數據的情況，如數據列表，可以使用**陣列**。

## 題目

請觀察以下情境，並推斷他適合哪種型別格式：

1. 情境：你需要儲存不同的使用者角色，如「管理員」、「使用者」和「訪客」。這些角色是固定的且有特定的名稱。
A. 列舉 (Enum)
B. 元組 (Tuple)
C. 陣列 (Array)
2. 情境：你正在開發一個函式，需要回傳一個包含經度和緯度的地理座標。
A. 列舉 (Enum)
B. 元組 (Tuple)
C. 陣列 (Array)
3. 情境：你需要一個儲存全台灣各家庭的數據資料，例如每個家庭的總年收入。
A. 列舉 (Enum)
B. 元組 (Tuple)
C. 陣列 (Array)
4. 情境：你需要表示一週的七天，每天都有一個特定的名稱。
A. 列舉 (Enum)
B. 元組 (Tuple)
C. 陣列 (Array)
5. 情境：你需要追蹤一個電子商務網站上的產品類別，這些類別已經固定，不會隨時間而更改。
A. 列舉 (Enum)
B. 元組 (Tuple)
C. 陣列 (Array)

## 開發題

### **題目標題: 設計一個訂單處理系統**

### 情境描述:

你正在開發一個電子商務系統，需要處理不同階段的訂單。為了更好地追蹤和管理訂單，你決定使用 TypeScript 的 **`enum`** 來表示訂單的各個處理階段。

### 任務:

1. 定義一個名為 **`OrderStatus`** 的 **`enum`**，其中包括以下狀態：待處理（Pending）、運送中（Shipping）、已送達（Delivered）、已取消（Cancelled）。
2. 建立一個函式，名稱為`changeOrderStatus`，藉此更新訂單狀態
- 參數：訂單 ID (**`orderId`**) 和新的訂單狀態 (**`newStatus`**)。
- 回傳：無（僅在控制台印出更新訊息）。

### 有欠缺的程式碼:

```tsx
enum OrderStatus

// 更新訂單狀態
function changeOrderStatus(orderId, newStatus) {
    
    console.log(`訂單 ${orderId} 的狀態已更新為：${newStatus}`);
}

// 範例使用
let orderId = 123; // 假設的訂單 ID

changeOrderStatus(orderId,訂單狀態);
```

<!-- 解答：  


單選題目：ABCAA

開發題：https://codepen.io/hexschool/pen/NWJbwve?editors=1011

```

-->

## 回報流程

將答案寫在 CodePen，並貼至底下回報就算完成了喔! 
解答位置請參考下圖（需打開程式碼的部分觀看）

![](https://i.imgur.com/vftL5i0.png)


回報區
---


|    Discord    |                          CodePen / 答案                          |
|:-------------:|:----------------------------------------------------------------:|
|洧杰|[Codepen](https://codepen.io/hexschool/pen/NWJbwve?editors=1011)|
|苡安|[Codepen](https://codepen.io/yi-an-yang/pen/vYPgNmZ)|
|Jack|[Codepen](https://codepen.io/lj787448952/pen/abMpvyv)|
|ZS|[Codepen](https://codepen.io/irishuang/pen/poYRjam)|
|HsienLu|[Codepen](https://codepen.io/Hsienlu/pen/GRerpBx?editors=1111)|
|BonnieChan|[Codepen](https://codepen.io/Bonnie-chan-the-bold/pen/eYXgprY?editors=1111)|
|hannahTW|[Codepen](https://codepen.io/hangineer/pen/LYaxprW?editors=1011)|
|YC|[HackMD](https://hackmd.io/SKoJd3EsTlitnjzCx4Rarg?view)|
|銀光菇|[CodePen](https://codepen.io/genesynthesis/pen/ExMZVmj)|
|皓皓|[HackMD](https://hackmd.io/@cutecat8110/H1ZNTzMKa)|
|hiYifang|[HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/SkhePfMKa)|
|LinaChen|[HackMD](https://codepen.io/LinaChen/pen/LYaxNQw)|
|m_m|[CodePen](https://codepen.io/minnn7716/pen/LYaxNvE)|
|rikku1756|[CodePen](https://codepen.io/rikkubook/pen/LYaxNwV?editors=1011)|
|黃士桓|[codePen](https://codepen.io/shr-huan-huang/pen/KKEaMyE)|
|Judy ☻|[Codepen](https://codepen.io/hsiaohan/pen/vYPgyNo?editors=1011)|
|Starr|[CodePen](https://codepen.io/StarrZhong/pen/qBvRqxG)|
|展誠|[Codepen](https://codepen.io/hedgehogkucc/pen/QWoddmz?editors=1012)|
|Henry_Wu|[Codepen](https://codepen.io/hekman1122/pen/xxBRbMQ?editors=1011)|
|Bryan Chu|[CodePen](https://codepen.io/bryanchu10/pen/poYRPaa)|
|Shaokang|[CodePen](https://codepen.io/tony-hsueh/pen/KKEgBKE?editors=1111)|
|Lisa|[CodePen](https://codepen.io/lisaha/pen/NWJdgKy)|
|wendy_.li|[HACKMD](https://hackmd.io/PcmFgqZwRd-4Ep3-LgK5_Q#TypeScript-%E9%99%A3%E5%88%97)|
|deedee1215|[CodePen](https://codepen.io/diddy032/pen/WNmRjVM)|
|Zuo|[CodePen](https://codepen.io/linchinhsuan/pen/abMpyOJ)|
|Yao|[CodePen](https://codepen.io/AlbertoLL/pen/oNVBepd)|
|77_0411|[CodePen](https://codepen.io/chung-chi/pen/BabpdjM?editors=1111)|
|jasperlu005|[Codepen](https://codepen.io/uzzakuyr-the-reactor/pen/WNmRELr?editors=1111)|
|Alyce|[Codepen](https://codepen.io/alycehwy/pen/abMpLxr?editors=0011)|
|Mi|[CodePen](https://codepen.io/Mi-Jou-Hsieh/pen/NWJdapd?editors=1100)|
|yunhung|[CodePen](https://codepen.io/ahung888/pen/XWGpVrd)|
|連小艾|[Codepen](https://codepen.io/bolaslien/pen/mdoRKqJ?editors=1012)|
JC|[Codepen](https://codepen.io/jcsamoyed/pen/wvOgYNd?editors=0012)
|Yang|[Codepen](https://codepen.io/Yang-J/pen/poYRGLd)|
|薏慈|[Codepen](https://codepen.io/its_wang/pen/MWxJdWm?editors=1010)|
|shan13|[Codepen](https://codepen.io/yishan13-tsai/pen/gOEgVWQ)|
|神奇海螺|[CodePen](https://codepen.io/ksz54213/pen/JjzWjyd)|
|Kai|[CodePen](https://codepen.io/kaiyuncheng-the-styleful/pen/mdoWJmb?editors=0012)|
|NiuNiu|[CodePen](https://codepen.io/Dawson-the-bold/pen/WNmRWqr?editors=0010)|
|Amberhh|[codepen](https://codepen.io/Amberhh/pen/QWopNRO?editors=1011)|
|clairechang|[Notion](https://claire-chang.notion.site/Day-6-Enum-34d445a092114876bdf154e1f98707b1)|
|erwin阿瀚|[CodePen](https://codepen.io/yohey03518/pen/JjzWKdg?editors=1010)
|Otis|[CodePen](https://codepen.io/humming74/pen/gOEmxrK?editors=1011) |
|翰毅|[CodePen](https://codepen.io/yzuigtdw-the-animator/pen/wvOJdNg?editors=1111)|
|fanshu0303|[CodePen](https://codepen.io/JuiHsuanLee0303/pen/xxBqoXv)|
|wei|[CodePen](https://codepen.io/jweeei/pen/ZEPedOM?editors=1011)|
|Teddy|[CodePen](https://codepen.io/TaideLi/pen/KKEmMWo)|
|精靈|[CodePen](https://codepen.io/justafairy/pen/VwRWaWB)|
|小米|[CodePen](https://codepen.io/joanne-wei/pen/rNRwpJB?editors=0012)|
|ethan1331|[CodePen](https://codepen.io/EthanTsai/pen/qBvjQLz) |
|leave3310|[CodePen](https://codepen.io/leave3310-the-looper/pen/VwRWJMJ?editors=0011) |
|zoe|[Codepen](https://codepen.io/Zoechiueh/pen/ZEPXPYO?editors=0011)|
|亞當|[Codepen](https://codepen.io/Adam-Hsu/pen/OJqOyzK?editors=0011)|
|Snorlax|[HackMD](https://hackmd.io/@snorlaxpock/SyjwMhiFa)|
|Nick Lin|[HackMD](https://codepen.io/NickLinP/pen/vYPpYVQ)|
|Yoshi|[CodePen](https://codepen.io/yoshiyyc/pen/XWGzPoo)|
|Rochel|[Codepen](https://codepen.io/rochelwang1205/pen/vYPpoOQ)|
|Eileen|[Codepen](https://codepen.io/Eileen-io/pen/GReQprx)|
|狸貓|[Codepen](https://codepen.io/tanuki320/pen/eYXrMaO?editors=1011)|
|阿鬥鬥|[HackMD](https://hackmd.io/yiFczUf9RrO4jceg5ZEdhQ?view#Day-6---%E5%88%97%E8%88%89%E5%9E%8B%E5%88%A5%EF%BC%88Enum%EF%BC%89)|
|aki|[codepen](https://codepen.io/aki168/pen/abMKOZE)|
|Tori|[HackMD](https://hackmd.io/OAdkiOH-S_WkD-LF6IONVA?view)|
puffy| [Codepen](https://codepen.io/TernMayDay/pen/OJqqQKg?editors=0011)
| 我是泇吟 | [CodePen](https://codepen.io/kljuqbxs/pen/bGPyddE) |