---
# System prepended metadata

title: "\U0001F3C5 Day 5 - 元組與聯合型別"
tags: [TypeScript 30 天證書培訓營 - 2024]

---

# Day 5 - 元組與聯合型別


## 元組

元組是 TypeScript 的一種特殊型別，允許將不同類型的元素儲存在單一陣列內。這於需要將多種數據型別組合在一起時非常有用。

### 特點有

1. 元組陣列長度是固定的
2. 元素順序在宣告時就會被確定
3. 允許不同型別的資料共存


```tsc=
let userInfo: [string, number];
userInfo = ["Alice", 30]; // 正確
userInfo = [30, "Alice"]; // 錯誤：型別對不上


let profile: [string, number] = ['Mary', 18];


function getStudentDetails(studentId: number): [number, string, string] {
    // 假設從資料庫獲得學生資訊
    return [studentId, "John Doe", "Physics"];
}

const [id, name, course] = getStudentDetails(101);
console.log(`Student ID: ${id}, Name: ${name}, Course: ${course}`);


```
## 元組常見使用時機一：函式返回多個值

當函式需要回傳多個值時，元組是一種非常方便的方式。允許你將多個值組合成一個緊湊的資料結構，並且每個值可以有不同的型別。

```typescript=
function getSize(): [number, number] {
    return [width, height];
}
```
## 元組常見使用時機二：解讀 CSV 格式

在解析 csv 資料蠻派得上用場的，因為 csv 的資料通常每筆資料在取值上型別都不相同


**HTML：**
```html=
<!DOCTYPE html>
<html>

<head>
    <title>CSV Parser</title>

</head>

<body>
    <input type="file" id="file-input" />


    <script src="parseCSV.js"></script>
</body>

</html>
```
**parseCSV.ts**
```typescript=
                                     // 元組型別
function parseCsv(content: string): [string, number, string][] {
    return content.split("\n").map(line => {
        const [name, ageString, position] = line.split(",");
        const age = parseInt(ageString, 10);
        return [name, age, position];
    });
}

function handleFileSelect(evt: any) {
    const file = evt.target.files[0];
    const reader = new FileReader();

    reader.onload = function(event) {
        const content = event.target.result as string;
        const employees = parseCsv(content);
        console.log(employees);
    };

    reader.readAsText(file);
}

document.getElementById('file-input').addEventListener('change', handleFileSelect, false);


```

**CSV 測試檔：employees.csv，請檔案儲存起來後，在 index.html 的 input file 加入後觸發 change 事件，便可看到 console 的資訊**

```csv=
John Doe,30,Developer
Jane Smith,25,Designer
Max Johnson,40,Manager
Emily Davis,35,Analyst
Alex Brown,28,Tester

```



## 聯合型別

在 TypeScript 中，聯合型別（Union Types）允許一個變數具有多個可能的型別。可增加程式碼的靈活性。


```tsx
// 範例程式碼 1
function printId(id: number | string) {
  console.log(`ID: ${id}`);
}

printId(123); // 輸出: ID: 123
printId("abc"); // 輸出: ID: abc

// 範例程式碼 2
function printResult(result: string | number) {
  if (typeof result === "string") {
    console.log(`Result: "${result}"`);
  } else {
    console.log(`Result: ${result}`);
  }
}

printResult("success"); // 輸出: Result: "success"
printResult(42); // 輸出: Result: 42

```


## 單選題

**題目一：下列哪個選項正確描述了元組？**
 - A. 元組是一種無序的資料結構
 - B. 元組可以包含不同類型的值
 - C. 元組的長度可以動態調整
 - D. 元組的元素可以被修改


**題目二：以下哪個描述最準確地表示 TypeScript 中的「聯合型別」？**

 - A. 聯合型別是一種將多個不同型別組合成一個型別的方式。
 - B. 聯合型別是一種用於表示陣列的型別。
 - C. 聯合型別是一種用於表示物件的型別。


**題目三：當我們想要表示多個不同型別的選項，並將它們合併成一個型別，我們應該使用什麼 TypeScript 功能？**

A. 元組
B. 聯合型別



**題目四：以下哪個 TypeScript 寫法表示一個元組（包含姓名和年齡）？**

A.

```tsx
const person: [string, number] = ["John", 30];

```

B.

```tsx
const person: [string] = ["John", 30];

```

C.

```tsx
const person: { name: string; age: number } = { name: "John", age: 30 };

```

D.

```tsx
const person: (string | number)[] = ["John", 30];

```


**題目五：**

以下哪個 TypeScript 寫法表示一個聯合型別（可以是字串或數字）？

A.

```tsx
const value: string = "Hello";

```

B.

```tsx
const value: string | number = "Hello";

```

C.

```tsx
const value: (string | number)[] = ["Hello", 42];

```

D.

```tsx
const value: { text: string } = { text: "Hello" };

```



**題目六：**

以下哪個 TypeScript 寫法表示一個函式參數的型別註釋（接受兩個數字並返回它們的和）？
PS:1/21 更新，調整為「函式參數」
A.

```tsx
const add = (a: number, b: number): number => a + b;

```

B.

```tsx
function add(a: number, b: number) {
  return a + b;
}

```

C.

```tsx
const add: (a: number, b: number) => number = (a, b) => a + b;

```

D.

```tsx
const add = (a, b) => a + b;

```


## 開發題
> 建議先看完 **[TypeScript 常用型別](https://courses.hexschool.com/courses/typescript-30/lectures/50717961)** 章節，再來挑戰此題目


請將以下待辦事項 JavaScript 程式碼，改為 TypeScript 版本，可隨意調整程式邏輯，只要確保有完成以下四項即可：
1. 可以新增待辦
2. 可以編輯待辦
3. 可以刪除待辦
4. 點擊待辦時，可以有劃線表示做完
```html=
<!DOCTYPE html>
<html>

<head>
    <title>Todo List</title>
</head>

<body>
    <h1>Todo List</h1>

    <!-- 待辦事項輸入框和按鈕 -->
    <input type="text" id="taskInput" placeholder="新增待辦事項">
    <button id="addTaskButton">新增</button>

    <!-- 待辦事項清單 -->
    <ul id="taskList">
        <!-- 在這裡顯示待辦事項項目 -->
    </ul>

    <!-- JavaScript 程式碼 -->
    <script>
        // 取得 HTML 元素
        const taskInput = document.getElementById("taskInput");
        const addTaskButton = document.getElementById("addTaskButton");
        const taskList = document.getElementById("taskList");

        // 儲存待辦事項陣列
        const tasks = [];

        // 建立新的待辦事項
        function createTask(taskText) {
            const task = {
                text: taskText,
                done: false
            };
            return task;
        }

        // 更新待辦事項列表
        function renderTaskList() {
            // 清空現有的清單項目
            taskList.innerHTML = "";

            // 依次處理每個待辦事項
            for (let i = 0; i < tasks.length; i++) {
                const task = tasks[i];

                // 建立一個待辦 DOM 元素
                const listItem = document.createElement("li");

                // 檢查是否已完成，如果是，添加完成樣式
                if (task.done) {
                    listItem.classList.add("done");
                }

                // 顯示待辦事項文字
                listItem.textContent = task.text;

                // 建立編輯按鈕
                const editButton = document.createElement("button");
                editButton.textContent = "編輯";
                editButton.addEventListener("click", () => {
                    const editedText = prompt("編輯待辦事項", task.text);
                    if (editedText !== null) {
                        task.text = editedText;
                        renderTaskList();
                    }
                });

                // 建立刪除按鈕
                const deleteButton = document.createElement("button");
                deleteButton.textContent = "刪除";
                deleteButton.addEventListener("click", () => {
                    const confirmDelete = confirm("確定要刪除這個待辦事項嗎？");
                    if (confirmDelete) {
                        tasks.splice(i, 1);
                        renderTaskList();
                    }
                });

                // 將編輯和刪除按鈕添加到待辦列表
                listItem.appendChild(editButton);
                listItem.appendChild(deleteButton);

                // 添加點擊事件監聽，切換完成狀態
                listItem.addEventListener("click", () => {
                    task.done = !task.done;
                    renderTaskList();
                });

                // 將該待辦添加到待辦列表中
                taskList.appendChild(listItem);
            }
        }

        // 新增待辦事項的事件監聽
        addTaskButton.addEventListener("click", () => {
            const taskText = taskInput.value.trim();

            // 確保輸入不為空
            if (taskText !== "") {
                const task = createTask(taskText);

                // 添加待辦事項到陣列中
                tasks.push(task);

                // 清空輸入框
                taskInput.value = "";

                // 重新渲染待辦事項清單
                renderTaskList();
            }
        });

        // 初始化時渲染待辦事項清單
        renderTaskList();
    </script>

    <!-- CSS 樣式 -->
    <style>
        .done {
            text-decoration: line-through;
        }
    </style>
</body>

</html>
```

<!-- 解答：  


單選題目：B、A、B、A、B、A



-->





回報區
---


|    Discord    |                          CodePen / 答案    |  開發題備註                        |
|:-------------:|:----------------------------------------------------------------:|:----------------------------------------------------------------:|
|洧杰|[Codepen](https://codepen.io/hexschool/pen/poYgYqW?editors=1010)| 有嘗試用 type、泛型~
|hannahpun|[Codepen](https://codepen.io/hannahpun/pen/LYaRKOL)
|展誠|[Codepen](https://codepen.io/hedgehogkucc/pen/qBvazPm?editors=1010)| 有嘗試用 type、泛型~~
|苡安|[Codepen](https://codepen.io/hedgehogkucc/pen/qBvazPm)| 有嘗試用 type
|ZS|[Codepen](https://codepen.io/irishuang/pen/yLwaddO)| 
|77_0411|[Codepen](https://codepen.io/chungchi/pen/jOJMgNb)| 
|hannahTW|[Codepen](https://codepen.io/hangineer/pen/LYabPQV?editors=0010)| 有嘗試用 interface~
|Jack|[Codepen](https://codepen.io/lj787448952/pen/gOELOav)|
|YC|[HackMD](https://hackmd.io/SKoJd3EsTlitnjzCx4Rarg)| 有嘗試用 interface |
|nina.kuo|[Codepen](https://codepen.io/ninakuo0814/pen/WNmGXPN)|
|hiYifang|[HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/B1VlA0_uT)|
|Otis|[Codepen](https://codepen.io/humming74/pen/VwRmLew?editors=1011)|
|Henry_Wu | [Codepen](https://codepen.io/hekman1122/pen/abMBzXR?editors=1010) |有嘗試用 type
|Bryan Chu|[CodePen](https://codepen.io/bryanchu10/pen/mdoOVvd)||
|jasperlu005|[Codepen](https://codepen.io/uzzakuyr-the-reactor/pen/JjzbXGV?editors=1010)|
|Zuo|[Codepen](https://codepen.io/linchinhsuan/pen/XWGNjKg)|有嘗試用 type |
|yunhung|[Codepen](https://codepen.io/ahung888/pen/abMBJgR)| 有嘗試用 type |
|銀光菇|[Codepen](https://codepen.io/genesynthesis/pen/qBvqXwL)| 有嘗試用 type
|Derrick|[Codepen](https://codepen.io/Derricktang/pen/NWJbaQz)|
|薏慈|[Codepen](https://codepen.io/its_wang/pen/VwRmrdr)| 有嘗試用 type
|leave3310|[Codepen](https://codepen.io/leave3310-the-looper/pen/MWxbOPw?editors=0010)| 有嘗試用 type
|BonnieChan|[Codepen](https://codepen.io/Bonnie-chan-the-bold/pen/BabQywy?editors=1010)|有嘗試使用type|
|Lisa|[Codepen](https://codepen.io/lisaha/pen/xxBRPor)|有嘗試使用interface|
|deedee1215 |[Codepen](https://codepen.io/diddy032/pen/XWGNzvp)|有嘗試用type、interface|
|rikku1756 |[Codepen](https://codepen.io/rikkubook/pen/gOELzJb?editors=1011)|有嘗試用type|
|Starr|[CodePen](https://codepen.io/StarrZhong/pen/oNVYyoN)|嘗試使用type, interface|
|m_m|[CodePen](https://codepen.io/minnn7716/pen/yLwVzVK)|嘗試使用 type|
|Teddy|[CodePen](https://codepen.io/TaideLi/pen/QWoGPed)|嘗試使用type, enum,泛型(一點點)|
|wei|[CodePen](https://codepen.io/jweeei/pen/dyrOLmg?editors=1010)|
|Mi|[CodePen](https://codepen.io/Mi-Jou-Hsieh/pen/QWoGpbw?editors=1000)|有嘗試用 interface|
|HsienLu|[CodePen](https://codepen.io/Hsienlu/pen/NWJdGRz)|有嘗試用interface|
|皓皓|[HackMD](https://hackmd.io/@cutecat8110/rkYlwwZF6)|有嘗試用 type|
| 黃士桓 | [codePen](https://codepen.io/shr-huan-huang/pen/BabpzjJ) | 使用type |
|wendy_.li| [HACKMD](https://hackmd.io/PcmFgqZwRd-4Ep3-LgK5_Q) | 使用type |
|shan13| [codePen](https://codepen.io/yishan13-tsai/pen/KKEaqWr) | |
|Amberhh| [codepen](https://codepen.io/Amberhh/pen/rNRjLNb)| 使用 interface|
|連小艾|[Codepen](https://codepen.io/bolaslien/pen/poYRKEw?editors=1010)|使用 type, as|
|JC|[Codenpen](https://codepen.io/jcsamoyed/pen/MWxbYab?editors=0011)|
| Rochel |[Codepen](https://codepen.io/rochelwang1205/pen/MWxJPpO?editors=1010)|
| LinaChen |[Codepen](https://codepen.io/LinaChen/pen/jOJMjYg)|有嘗試用 interface|
| NiuNiu |[Codepen](https://codepen.io/Dawson-the-bold/pen/mdoRLWz?editors=0010)|
erwin阿瀚|[CodePen](https://codepen.io/yohey03518/pen/wvOgVQw?editors=0010)
| clairechang |[Notion](https://claire-chang.notion.site/Day-5-96d412deb68f4680a9749015e07791c6)|interface|
| Alyce |[Codepen](https://codepen.io/alycehwy/pen/yLwgBRq)|有嘗試用type|
| Kai |[Codepen](https://codepen.io/kaiyuncheng-the-styleful/pen/KKEWKeb?editors=1010)|有嘗試用type|
| 神奇海螺|[CodePen](https://codepen.io/ksz54213/pen/GReWZzZ)| 使用 interface|
| 翰毅 |[Codepen](https://codepen.io/yzuigtdw-the-animator/pen/VwRPqMx)|有嘗試用type|
| bonnieli1414 |[Codepen](https://codepen.io/bonnieli1414/pen/mdoWBRZ?editors=0011)||
| fanshu0303 | [CodePen](https://codepen.io/JuiHsuanLee0303/pen/RwdpzRr) ||
| MCBB_4881 |[CodePen](https://codepen.io/ebvaxaah-the-bashful/pen/OJqmJNW?editors=1010)|使用 interface|
|時雨|[CodePen](https://codepen.io/jjustin-35/pen/jOJmEpN?editors=1111)|使用 type, as |
| 精靈 | [CodePen](https://codepen.io/justafairy/pen/wvOeapw) | 有嘗試使用 type, as |
|Snorlax|[HackMD](https://hackmd.io/@snorlaxpock/H1rsvIqFp)|
|小米|[HackMD](https://codepen.io/joanne-wei/pen/wvOdQMo)|使用type
|ethan1331|[CodePen](https://codepen.io/EthanTsai/pen/dyrpmNV)|
|Yoshi|[CodePen](https://codepen.io/yoshiyyc/pen/dyrRyoL)| 有使用 type |
|aki|[codepen](https://codepen.io/aki168/pen/ZEPXavy)|
|zoe|[Codepen](https://codepen.io/Zoechiueh/pen/xxBXJvy?editors=1011)|
|亞當|[Codepen](https://codepen.io/Adam-Hsu/pen/vYPWOvd?editors=0010)|使用 interface|
|Nick Lin|[Codepen](https://codepen.io/NickLinP/pen/RwdLvgL?editors=1111)|使用 type|
|Eileen|[Codepen](https://codepen.io/Eileen-io/pen/YzgeXOG)|使用 type|
|狸貓|[Codepen](https://codepen.io/tanuki320/pen/GRedxpj?editors=0010)|有嘗試使用 type, as|
|Tori|[Codepen](https://hackmd.io/OAdkiOH-S_WkD-LF6IONVA?view)|使用 type、interface、as|
puffy|[Codepen](https://codepen.io/TernMayDay/pen/abMMqrg?editors=1010)|有嘗試使用 type, as
| 我是泇吟 | [Codepen](https://codepen.io/kljuqbxs/pen/VwJNVgz) | 有嘗試使用 type interface 泛型 |




