---
# System prepended metadata

title: 跑完 JS30 就接著認識 TypeScript 入門｜Day01：型別註記、型別斷言與型別推論
tags: [跑完 JS30 就接著認識 TypeScript 入門]

---

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

在聊註記、斷言以及推論之前，我們先來快速認識一下 TS 的型別有哪些。

## 型別類型
此處所列的類型，並非官方分類，是依書籍作者（Maxwell Huang）的分類為依據，筆者認為對於認識 TypeScript 的型別有很大的幫助。

> 書籍原始文章：[讓TypeScript成為你全端開發的ACE！- Maxwell Huang](https://ithelp.ithome.com.tw/users/20120614/ironman/2685)

型別大致分為六種：**原始型別**、**物件型別**、**明文型別**、**特殊型別**、**複合型別**、**泛用型別**，以下簡單介紹：

### 原始型別（Primitive Types）
包含 `number`, `string`, `boolean`, `undefined`, `null`, `symbol`, `void`。

### 物件型別（Object Types）
此型別可再細分三種型別：
- 基礎物件型別：`Object`, `JSON`, `Array`, `Class`
- TS 內建擴充型別：`Enum`, `Tuple`
- 函式型別：`function`, `arrow function`

### 明文型別（Literal Type）
一個值本身可成為一個型別。

舉例來說，將字串 `"Hello TS"` 變成某變數的型別，則變數值只能是 `"Hello TS"`，當然，這麼做的意義並不大，因此大部分看到的會是 `Object Literal Type`。

### 特殊型別（非官方分類）
包含 `any`, `never`, `unknown`。

### 複合型別（Composite Type，非官方分類）
包含 `union` 與 `intersection` ，此型別通常由邏輯運算子（`|`, `&`）組成。

### 泛用型別（Generics Types）
> 此型別中譯由 `通用型別` 改為 `泛用型別` ，修正參考 [此篇](https://ithelp.ithome.com.tw/articles/10216794)。

泛用型別，就是將 `型別化名` 進行參數化（Parameterize）的行為，其中 `型別化名` 會於 [`明文型別` 的篇章](https://hackmd.io/@elzuoc/rkcMxJJx3#%E5%9E%8B%E5%88%A5%E5%8C%96%E5%90%8D-Type-Alias)進行說明。

---
## 型別註記、斷言與推論

### 型別註記（Type Annotation）
就是將型別註記在程式碼中，因此，有固定的註記形式，以下使用 `~` 底線標註。

#### 註記形式一：註記在 `變數後方`， `等號前方`
```typescript=
const msg: string = 'Hello TS';
//       ~~~~~~~~~

let randomNum: number = Math.random();
const isExist: boolean = true;
```

#### 型別註記二：註記在 `函式陳述式` 宣告時
```typescript=
// JavaScript
function isPositive(input) {
    return input > 0;
}

// TypeScript
function isPositive(input: number): boolean {
    //                    ~~~~~~~ ~~~~~~~~~
    return input > 0;
}
```

#### 型別註記三：註記在 `函式表達式` 宣告時
> 請留意此處的 `() => boolean` 並非 `arrow function`！
> 仔細觀察可發現 `=` 號後方都未改變，`註記` 統一都在前方。

```typescript=
// JavaScript
const isPositive = function(input) {
    return input > 0;
}

// TypeScript
const isPositive: (input: number) => boolean = function(input) {
    //          ~       ~~~~~~~~  ~~~~~~~~~~
    return input > 0;
}
```

#### 型別註記四：註記在 `Arrow Function` 宣告時
> 仔細觀察可發現 `=` 號後方都未改變，`註記` 統一都在前方。
> 
```typescript=
// JavaScript
const isPositive = (input) => input > 0;

// TypeScript
const isPositive: (input: number) => boolean = (input) => input > 0;
//              ~       ~~~~~~~~  ~~~~~~~~~~
```

#### 型別註記五：註記在 `Arrow Function` 宣告時
> 這是註記 **唯一** 寫在 `=` 後方的寫法，有點類似 `函式陳述式`
```typescript=
const isPositive = (input: number): boolean => input > 0;
```

### 型別斷言（Type Assertion）
只要使用 TS 關鍵字 `as` 或 `<T>(...)` 的格式，就是斷言的用法。
> 仔細觀察可發現 `=` 號前方都未改變，`斷言` 統一都在後方。

#### 斷言形式一：斷言在 `未知的值`
```typescript=
const num = returnUnknown() as number;
//                          ~~~~~~~~~
const num = <number>(returnUnknown());
//          ~~~~~~~~
```

#### 斷言形式二：斷言在 `Arrow Function` 宣告時
> 仔細觀察可發現 `=` 號前方都未改變，`斷言` 統一都在後方。
```typescript=
// JavaScript
const isPositive = (input) => input > 0;

// TypeScript
const isPositive = ( (input) => input > 0 ) as (input: number) => boolean
// ( () => {} ) as (input: number) => boolean
// 斷言在 arrow function 之後

const isPositive = <(input: number) => boolean>( (input) => input > 0 );
// <(input: number) => boolean>( () => {} )
// 斷言在 arrow function 之前
```


### 型別推論（Type Inference）
- 不需要像註記一樣，由工程師手動編寫至程式碼中
- 型別推論內建於 TS 中，由 TS 主動監測，並推論前後撰寫的變數與值，型別是什麼，以及型別是否一致。

因此，如果指派其他型別的值，到被推論後的變數，則 TS 便會提醒或顯示警告。

## 結論
型別註記與型別斷言非常相似，不過斷言可用於型別轉換：

```typescript=
let sayA: any = 'hello';
let sayB: string = sayA as string;
```
在這個範例中，宣告了一個變數 `sayA` 型別為 `any`，不過在宣告 `sayB` 時，則透過 `型別斷言` 強制將 `sayA` 型別轉換為 `string` 後，才將值賦予給 `sayB`。

要特別留意的是，型別斷言執行時不會進行任何檢查，如果轉換錯誤，可能會導致執行錯誤。

因此，在使用斷言進行型別轉換時，務必要確保轉換的類型是正確的。


---
### Reference
- [讓TypeScript成為你全端開發的ACE！Day 02 - 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)
> 上一篇：[Day00：JavaScript 與 TypeScript](https://hackmd.io/@elzuoc/HJ9EDPv1n)
> 下一篇：[Day02：型別系統 - 原始型別 Primitive Types](https://hackmd.io/@elzuoc/B1zeGU61n)

###### 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 13, 2023
###### 文章若有任何錯誤，還請不吝給予留言指正，謝謝大家！