# TypeScript - 原始資料型別、空值與任意值 ## Data Types 原始資料型別 Javascript [資料型別(Data types)](https://hackmd.io/tW7ORGtMTCmKHtm8lA2WGA)分為「原始資料型別(Prmitive types)」和「物件型別(Object types)」兩種。 **原始資料型別**包含這六種:`boolean`(布林值)、`number`(數字)、`string`(字串)、`null`(無值)、`undefined`(未定義值)與 `symbol` (標識符,ES6 才出現)。 ## Boolean 布林值 TypeScript 中使用 `boolean` 來標示布林值: ```typescript let isDone: boolean = false; function isEven(num: number): boolean{ return num % 2 === 0 } ``` 需注意:使用**建構函式 Boolean 建立的是一個物件**不是布林值: ```typescript let isNewBoolean: boolean = new Boolean(1); // Type 'Boolean' is not assignable to type 'boolean'. // 'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible. ``` ```javascript let newBoolean = new Boolean(1) typeof(newBoolean) // 'object' let isNewBoolean = Boolean(1); typeof(isNewBoolean) // 'boolean' ``` `new Boolean` 返回的是一個物件;直接呼叫 `Boolean` 返回的是 `boolean` 型別 其他基本型別像是 `number` 與 `string` 對應的建構函示 `Number` 和 `String` 也是如此。(`null` 和 `undefined` 除外) ## Number 數字 TypeScript 中使用 `number` 來標示數字: ```typescript // 十進位 let decimalNumber: number = 6; // 十六進位 let hexadecimalNumber: number = 0xf00d; // 二進位 (ES6 中的二進位制表示法) let binaryNumber: number = 0b1010; // 八進位 (ES6 中的八進位制表示法) let octalNumber: number = 0o744; // NaN (Not a Number) 值,表示非數字結果 let notANumberValue: number = NaN; // 無窮大數字值 let infinityValue: number = Infinity; ``` 編譯成 Javascript 的結果: ```javascript var decimalNumber = 6; var hexadecimalNumber = 0xf00d; var binaryNumber = 10; // 二進位數字會被編譯成十進位數字 var octalNumber = 484; // 八進位數字會被編譯成十進位數字 var notANumberValue = NaN; var infinityValue = Infinity; ``` [ES6 中的二進位制和八進位制表示法](http://es6.ruanyifeng.com/#docs/number#%E4%BA%8C%E9%80%B2%E4%BD%8D%E5%88%B6%E5%92%8C%E5%85%AB%E9%80%B2%E4%BD%8D%E5%88%B6%E8%A1%A8%E7%A4%BA%E6%B3%95)會被編譯為十進位制數字 ## String 字串 TypeScript 中使用 `string` 來標示字串: ```typescript let myName: string = 'Tom' function greet(person: string): string { return `Hello, ${person}!` } greet(myName) ``` 編譯成 Javascript 的結果: ```javascript "use strict"; let myName = 'Tom'; function greet(person) { return `Hello, ${person}!`; } greet(myName); ``` ## Void 空值、 Null 和 Undefined ### Void 空值 Javascript 本身沒有空值(Void)的概念,TypeScript 中使用 `void` 這個**特殊型別**來標示**沒有返回任何值的函式**: ```typescript function alertName(name: string): void { alert(`My name is ${name}`) } ``` 宣告 `void` 型別的變數沒有什麼太大的用處,因為你只能將它賦值為 `null` 和 `undefined` 這兩個特殊的子型別: ```typescript let voidVariable: void = undefined; ``` ### Null 和 Undefined TypeScript 中使用 `null` 和 `undefined` 來標示這兩個原始資料型別: ```typescript let undefinedVariable: undefined = undefined; let nullValue: null = null; ``` > **`undefined` 和 `null` 是所有型別的子型別**。 **`null` 和 `undefined` 型別的變數,可以賦值給其他型別的變數**,例如 `string` 或 `number`(除非啟用了 `strictNullChecks` 選項): ```typescript // 這樣不會報錯 let x: number = undefined; let y: string = null; // 這樣也不會報錯 let u: undefined; let num: number = u; ``` 而 **`void` 型別的變數不能賦值給 `number` 型別的變數**: ```typescript // 但這樣會報錯 let v: void; let num: number = v; // Type 'void' is not assigned to type 'number'. ``` #### strictNullChecks 在啟用 `strictNullChecks` 選項時,需要明確地指定變數可以為 `null` 或 `undefined`: ```typescript! let x: number | null = null; let y: string | undefined = undefined; ``` #### 啟用 `strictNullChecks` 選項 在 `tsconfig.json` 將 strictNullChecks 選項設定為 `true`: ```json { "compilerOptions": { "strictNullChecks": true, //... } } ``` ## 任意值 Any 普通的型別是不可以在賦值過程中改變型別的: ```typescript let age: string = 'five' age = 7 //index.ts:2:1 - error TS22322: Type 'number' is not assignable to type 'string' ``` 在 TypeScript 中使用 `any` 這個**特殊型別**來表示允許被賦值為**任意型別**: ```typescript let anything: any = 'five' anything = 7 anything = [0,1,2] anythinge.foo = 'bar' anything() ``` ### 任意值的屬性和方法 被標示為 `any` 型別的變數,即使**存取不存在的屬性**或**呼叫不存在的方法**也都是允許的: ```typescript! let anything: any = { myName: 'John'} console.log(anyType.myAge) // 不會報錯,即使屬性 'myAge' 不存在 ``` ```typescript let anything: any = 'Tom' anything.setName('Jerry')// 不會報錯,即使方法 'setName' 不存在 ``` **當我們宣告一個變數並標示其為 `any` (任意值)型別後,對它的任何操作,返回的值的型別也都會是 `any` (任意值)。** ### 未宣告型別的變數 變數在宣告的時候如果**沒有指定任何型別也沒有給予初始值**(依照 TypeScript 型別推論(Type Inference)也無法推斷),就會被識別為為 `any` (任意值)型別。 ```typescript let something // 等同於 let something: any something = 'seven' something = 7 something.setName('Tom') ``` ## Ref - [TypeScript 新手指南 (gitbook.io)](https://willh.gitbook.io/typescript-tutorial/) - [從零開始學 TypeScript 計畫](http://anna-yufeng.com/)