---
# System prepended metadata

title: 跑完 JS30 就接著認識 TypeScript 入門｜Day04：型別系統 - 明文型別 Literal Types 與 型別化名
tags: [跑完 JS30 就接著認識 TypeScript 入門]

---

---
GA: G-7BSJTG7RYN
---

### Literal 究竟是什麼
`Literal` 直接翻譯是 `字面上的`，所以 Literal Type 白話一些就是指 **字面上的型別**。

> 也就是字面上顯示的格式，在你看來是 **什麼** 型別，它就是 **什麼** 的明文型別。

進一步來看，`Object`, `Function`, `Array`, `Tuple`, `Enum`，各自都是一個型別，但**廣義**來說，都是 `明文型別` 的**表示方式**。

簡單來說，`明文型別` 可以視為是眾多表示方式的集合體。

直接看個範例，當我這樣宣告一個物件：
```typescript=
let info = {
    name: 'Connie',
    age: 18,
    hasMobile: true,
};
```
透過 TS 的型別推論機制，`info` 型別結果會是一個完整的 `Object 格式`，而不是只顯示文字 `Object`，而這樣的表示方式，就稱為**物件的明文型別（Object Literal Type）**
```typescript=
// Object Literal Type
{
    name: string,
    age: number,
    hasMobile: boolean
}
```

再多看一個例子，當我這樣宣告一個函式：
```typescript=
let addition = function(paramA: number, paramB: number) {
    return paramA + paramB;
}
```

透過 TS 的型別推論機制，`addition` 型別結果會是一個 `Function 格式`，而不是只顯示文字 `Function`，而這樣的表示方式，就稱為**函式的明文型別（Function Literal Type）**
```typescript=
// Function Literal Type
let addition: (paramA: number, paramB: number) => number
```
--
### 型別化名 Type Alias
主要的功用在於 **簡化程式碼** 及 **抽象化型別（Type Abstraction）**。

其實，這兩個概念可以說幾乎是同時存在的。

`抽象化`：將具體的細節隱藏起來，只提供一個接口或功能給使用者。

我們直接來看範例會更清楚：
```typescript=
function showPerson(person: { name: string; age: number }) {
  return `${person.name} is ${person.age} years old.`;
}
```
> **小提醒**
> 還記得在 TS 中我們必須要進行 `型別註記` 嗎？
> 在這裡參數我們註記為 **物件明文型別** `: { name: string; age: number }`

如果宣告了許多需要傳入這個型別參數的 `function`，是不是覺得很累贅？
這時候我們就會進行 **型別化名**。

型別化名必須使用關鍵字 `type` 來創建：

```typescript=
type Person = {
  name: string,
  age: number,
};
```

可以看到我們將剛剛的物件明文型別**化名**為 `Person`，接著使用它：

```typescript=
function showPerson(person: Person) {
  return `${person.name} is ${person.age} years old.`;
}
```

我們提供了一個 `Person` 在宣告時使用，但光看 `Person` 我們無法得知實際的內容是什麼，也就是前述所說的，**將具體的細節隱藏起來**，這個過程就稱為 **抽象化**，同時也 **簡化程式碼**。

--
### 選用屬性 Optional Properties
現在，假設我們有個會員表單，有一欄生日是 `birthday` ，而這欄非必填。

我們試著創建型別化名：
```typescript=
type Member = {
  name: string,
  age: number,
  birthday: Date,
};
```
這時若使用者未填寫 `birthday`，系統就會出錯，因為這欄必須為 `Date` 型別。

再看一個狀況：
```typescript=
let createConnie: Member = {
  name: 'connie',
  age: 18,
};
```

此處在建立新的會員的靜態資料時，選擇不傳入 `birthday`， TS 也會聰明的提出警告。

因此，針對 `birthday` ，我們就會使用 **選用屬性**，也就是在屬性後多一個 `?` 問號：
```typescript=
type Member = {
  name: string,
  age: number,
  birthday?: Date,
};
```

---
### Reference
- [讓TypeScript成為你全端開發的ACE！- Maxwell Huang](https://www.books.com.tw/products/0010859134)
- [讓 TypeScript 成為你全端開發的 ACE！ 系列 - 第 11 屆 iThome 鐵人賽](https://ithelp.ithome.com.tw/users/20120614/ironman/2685)
- [TypeScript Official Site](https://www.typescriptlang.org/docs)
- [Scala day 5 (function literal) - daniel0614](https://ithelp.ithome.com.tw/articles/10191032)
---

> 系列：[`跑完 JS30 就接著認識 TypeScript 入門`](https://hackmd.io/@elzuoc?tags=%5B%22%E8%B7%91%E5%AE%8C+JS30+%E5%B0%B1%E6%8E%A5%E8%91%97%E8%AA%8D%E8%AD%98+TypeScript+%E5%85%A5%E9%96%80%22%5D)
> 上一篇：[Day03：型別系統 - 物件型別 Object Types](https://hackmd.io/@elzuoc/SJhyv8612)
> 下一篇：[Day05：型別系統 - Never、Any、Unknown](https://hackmd.io/@elzuoc/Skd3Uree3)

###### tags: [`跑完 JS30 就接著認識 TypeScript 入門`](https://hackmd.io/@elzuoc?tags=%5B%22%E8%B7%91%E5%AE%8C+JS30+%E5%B0%B1%E6%8E%A5%E8%91%97%E8%AA%8D%E8%AD%98+TypeScript+%E5%85%A5%E9%96%80%22%5D)

###### Created on ∥ March 16, 2023
###### 文章若有任何錯誤，還請不吝給予留言指正，謝謝大家！