深入探討 TypeScript 之基本型別
TypeScript 既然稱為 TypeScript,想當然爾型別就是該語言的重頭戲,本文我們來看看 TypeScript 對於 JavaScript 增加了哪些型別支援。
Version
TypeScript 2.3
Boolean
1 | let isDone: boolean = false; |
若值只有 true 與 false,則其型別為 boolean。
1 | let isDone = false; |
若變數可直接由初始值 true 或 false 獲得型別,language service 會加以提示省略型別宣告,但 isDone 本質仍是強型別 boolean,編譯器會加以檢查,只是程式不用宣告 boolean 而已。
Number
1 | let decimal: number = 6; // 十進位 |
TypeScript 與 JavaScript 一樣,數字只有 number 型別,且本質是浮點數,不像 C# 數字有 int 、 float 與 double。
1 | let decimal = 6; |
若變數可直接由初始值數字獲得型別,language service 會加以提示省略型別宣告,但變數本質仍是強型別 number,編譯器會加以檢查,只是程式不用宣告 number 而已。
String
1 | let firstName: string = "Sam"; |
TypeScript 與 JavaScript 一樣,提供 string 型別,有 3 種表示法:
- 雙引號
- 單引號
- Backtick
其中 backtick 寫法,稱為 template string,可配合變數直接鑲在字串內,而不用靠 + 湊字串,可讀性較高,實務上建議使用。
1 | let firstName = "Sam"; |
若變數可直接由初始值字串獲得型別,language service 會加以提示省略型別宣告,但變數本質仍是強型別 string,編譯器會加以檢查,只是程式不用宣告 string 而已。
雖然 TypeScript 允許 string 使用雙引號,但 language service 會提示建議使用單引號。
Array
1 | let list: number[] = [1, 2, 3]; |
TypeScript 對於陣列提供兩種寫法:
- 傳統 JavaScript 風格寫法。
- 泛型風格寫法。
兩種寫法可讀性都很高,實務上都推薦,只要團隊取得共識要使用哪種寫法即可。
Tuple
1 | let x: [string, number]; |
陣列必須每個元素的型別都相同,若你希望陣列中有不同型別的元素,則應該使用 tuple。
實務上若你希望 function 回傳多值,且型態不相同,則可使用 tuple。
Enum
1 | enum Color {Red, Green, Blue} |
Enum 型別是強型別語言的代表,從 C 語言就已經有 enum,C++ 與 C# 也有 enum,但 JavaScript 一直都沒有 enum (未來有的機會也不高),TypeScript 將之補上,它有幾個優點:
- 參數之間的傳遞不用在使用 magic number,可以透過 enum 取可讀性更高的名字。
- Number 不用再直接輸入,可由 enum 型別透過 intellisense 自動帶出。
- 若輸入 enum 型別沒有的數字,編譯器會幫我們擋下來。
TypeScript 2.4 的 enum 即將支援字串,讓我們透過 enum 可以確保所輸入的是我們要的字串。
Any
1 | let notSure: any = 4; |
對於 JavaScript legacy code 或 3rd party library,若一時導入 TypeScript 有其困難,可先暫時宣告為 any 放生,讓 TypeScript 不做型別檢查,日後再慢慢重構成適當型別。
實務上不建議使用 any 型別,因為這將喪失 TypeScript 的型別檢查機制,除非有充分的理由。
Void
1 | function warnUser(): void { |
若 function 明確不傳回任何值,可宣告為 void 型別,若將此 function 的回傳值指定為變數,將編譯失敗。
Null 與 Undefined
null 與 undefined 一直是寫 JavaScript 很惱人的問題,我們必須在程式碼內判斷輸入的參數是否為 null 或 undefined。
1 | // Compiled with --strictNullChecks |
在 TypeScript 2.0 提供了 strict null check,可以幫我們檢查參數是否為 null 或 undefined。
若我們參數明確要接受 null 或 undefined,則必須在參數用 | 明確宣告,否則預設不接受 null 與 undefined。
a 可接受的型別為 number ,不接受 null 與 undefined ,但 b 可接受的型別為 number、null ,不接受 undefined。
若輸入的參數 a 為 null 或 undefined,將編譯失敗。

Angular 預設並沒有啟動 strictNullChecks,須在專案根目錄的 tsconfig.json 的 compilerOptions 加上 strictNullChecks 為 true,TypeScript 才會啟動 strictNullChecks。
Never
1 | function error(message: string): never { |
有些 function 永遠不傳回值,只會拋出 exception 或無窮回圈,雖然可以回傳 void,但語意上並不精確,TypeScript 另外提出 never 型別,專門對付 exception 或無窮迴圈。
若將回傳 never 型別的 function 指定給變數,將編譯失敗。
Type Assertion
1 | let someValue: any = 'this is a string'; |
或
1 | let someValue: any = 'this is a string'; |
實務上有時宣告了 any,但為了 intellisense 或其他變數,需要做明確的轉型,此時可使用 type assertion 明確轉型,也就是告訴編譯器:
- 我自己知道此變數的明確型別,請相信我的轉型。
雖然 type assertion 有兩種寫法,實務上建議使用第一種,第二種是為了 React 的 JSX 所妥協的語法,在 Angular 用不到。
Conclusion
- 透過 TypeScript 的明確型別宣告,可以讓編譯器幫我們檢查傳入參數是否符合型別,不用再寫一堆程式判斷。
enum在實務上非常用有,建議大家多用。- 建議大家將
strictNullCheck打開,讓 TypeScript 編譯器幫我們檢查惱人null與undefined。