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