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