---
GA: G-7BSJTG7RYN
---
在 [<Day00:JavaScript 與 TypeScript>](https://hackmd.io/@elzuoc/HJ9EDPv1n) 我們有提過,TypeScript 是 JavaScript 的 Superset,因此有許多的型別源自於 JS。
在 TypeScript 中,物件型別還可再細分三種型別:`基礎物件型別`、`TS 內建擴充型別`、`函式型別`。
若跑過 JS30,應該對 JS 有一定的熟悉度,那我們便會發現在 `物件型別` 細分的三種類型中,只需要多認識一種類型即可。
### 存在於 JavaScript 的型別
- 基礎物件型別:`Object`, `JSON`, `Array`, `Class`
- 函式型別:`function`, `arrow function`
### TypeScript 增加的型別
- TS 內建擴充型別
`Enum`(Enumerate,**列舉**):可將變數的範圍限制住,並在限制下進行存取。
`Tuple`(**元組**):可固定陣列元素數量及各元素型別,不過型別不須相同。
接下來針對這兩個新的型別,深入瞭解一下:
### Enum 運用
使用 Enum 宣告的目標,可視為是一個資料集合,而屬於集合的元素,必須具備 3 項特質:
1. 互異性:元素值不重複。 *(若元素值會重複,建議使用陣列)*
2. 無序性:元素沒有順序問題。
3. 確定性:可列舉出的元素是固定的。
> 需要特別注意的是, enum 宣告和物件的撰寫方式很相似,都是使用 `{}`,但變數後沒有 `=` 號,且內部元素必須用 `=` 賦值,而非 `:`。
#### Numeric enums
```typescript=
enum Direction {
Up = 1,
Down,
Left,
Right,
}
```
我們宣告一個 `enum` 型別的變數 `Direction`,其中 `Up` 元素值初始化設定為 `1`,接下來的元素值若沒有特別寫,就會接續自動給號(auto-incremented),也就是 `Down = 2`, `Left = 3`, `Right = 4`。
若沒有初始化任何元素值:
```typescript=
enum Direction {
Up,
Down,
Left,
Right,
}
```
那麼元素的起始值會自 `0` 開始,也就是 `Up = 0`, `Down = 1`,依此類推。
#### String enums
不同於 `Numeric enums` ,`String enums` 不會自動給值,因此賦值必須給予字串或 `String enums`。
```typescript=
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
```
#### Heterogeneous enums
> 混和 `Numeric` 與 `String`
> ★ 不建議這樣使用
```typescript=
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
```
### Tuple 運用
跟 `Array` 很類似,不過 `Tuple` 有3項特質:
1. 元素數量是固定的
2. 元素順序與型別宣告順序,必須完全吻合
3. 各元素型別不須相同
直接舉例看 `Array` 與 `Tuple` 宣告的差異:
```typescript=
// Array
type arrayType = (string | Date)[];
// Tuple
type tupleType = [string, string, string, Date];
```
雖然 `Tuple` 對於順序有嚴格要求,仍有缺點。
假設宣告一個 `Tuple`,依序放入 `品牌`, `型態`, `顏色`, `出廠日期`:
```typescript=
type Vehicle = [string, string, string, Date];
let BMWVehicle: Vehicle = ['BMW', 'motorcycle', 'silver', new Date(2023, 3, 16)];
```
看似沒問題,但若將 `BMW` 和 `motorcycle` 對調呢?
```typescript=
let BMWVehicle: Vehicle = ['motorcycle', 'BMW', 'silver', new Date(2023, 3, 16)];
```
其實 TypeScript 不會進行警告,因為 TS 只會比對型別,而這兩欄的型別比對後,是正確的,就不會產生錯誤警告。
因此,這類型的資料,還是建議使用 `Object` 進行宣告與取用:
```typescript=
let vehicle = {
brand: 'BMW',
type: 'motorcycle',
color: 'silver',
manufactureDate: new Date(2023, 3, 16)
};
```
這種方式,就會透過 TS 機制,型別推論為:
```typescript=
{
brand: string,
type: string,
color: string,
manufactureDate: Date
}
```
---
### Reference
- [【Day 12】TypeScript 資料型別 - 元組(Tuple) & 列舉(Enum)- Kira](https://ithelp.ithome.com.tw/articles/10221546)
- [[TypeScript] 列舉型別 ( Enumerate)- Charlie H.](https://medium.com/@notwist123/typescript-%E5%88%97%E8%88%89%E5%9E%8B%E5%88%A5-enumerate-96fc2eedd581)
- [讓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)
---
> 系列:[`跑完 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)
> 上一篇:[Day02:型別系統 - 原始型別 Primitive Types](https://hackmd.io/@elzuoc/B1zeGU61n)
> 下一篇:[Day04:型別系統 - 明文型別 Literal Types 與 型別化名](https://hackmd.io/@elzuoc/rkcMxJJx3)
###### 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 15, 2023
###### 文章若有任何錯誤,還請不吝給予留言指正,謝謝大家!