{%hackmd BJrTq20hE %} ###### tags: `TypeScript` # TypeScript基礎類型 ## TypeScript會自動推斷該變數的型別,在一般的情況之下不用特別定義他的型別 例如: ``` let name = "John"; name = 123; ``` 會如下圖所示,判斷name 要為string所以name被賦值為number時有警報 ![](https://i.imgur.com/m45TYXc.png) ## 特別定義型別的情況 但是如果沒有賦值的時候則需要特別定義他的型別,否則型別會預設為any,如下圖 ``` let name; ``` ![](https://i.imgur.com/ql690yB.png) 這個時候可以任意賦值,不會報錯。 這個時候就需要先定義型別 ``` let name: string; ``` 另外布林與數字也是一樣的方法 ``` let isTrue = false; isTrue = true; let isFalse: boolean; ``` ![](https://i.imgur.com/krHtHS3.png) ![](https://i.imgur.com/nt16QWX.png) ``` let num = 456; num = 123; let numx:number; ``` ![](https://i.imgur.com/DNSOMRs.png) ![](https://i.imgur.com/eV4h8QZ.png) ## undefine與null 這兩個比較特別,並不會觸發由變數判斷型別的功能,而是先定義為any 在以下範例的時候這兩個型別都會先被定義成any ``` let nu = undefined; let n1 = null; ``` ![](https://i.imgur.com/R4HWtAm.png) ![](https://i.imgur.com/5oyOqqg.png) 如果特別需要定義型別的話則需要如下 ``` let nu: undefined = undefined; let n1: null = null; ``` ![](https://i.imgur.com/pdfznaA.png) ![](https://i.imgur.com/fGIKmnk.png) 此外未賦值但有需要先定義型別的話,處理方法也與純值相同 ``` let nu: undefined; let n1: null; ``` ![](https://i.imgur.com/kEzAzAo.png) ![](https://i.imgur.com/w7t31lf.png) ## 避免使用any any的使用 ``` let price: any=123; price = false; ``` 原本應該會報錯的程式碼在使用any的時候就不會報錯。 any型別應該是測試的時候使用,如果大量使用any就會失去了使用TS的目的,某些型別的bug就只能在程式運行的時候才能得知了。 ## TypeScript Array與tuple 在TypeScritp的Array也與純值一樣,只要一開始賦值的Array內有多少種類型的資料那個Array就只能存取多少種類 例如: ``` const arr = [1,"2",3]; // arr只能push number與string arr.push(false) ``` 如果push與原始賦值的資料不同的型別則會出錯 ![](https://i.imgur.com/lL1AOaq.png) ### 也可以直接寫出array內的資料類別 下面的例子就表示arr2內部的資料只能有string與boolean ``` const arr2: (boolean | string)[] = ["string", false]; ``` ### 只有一種資料類別的Array寫法有三種 ``` const arr3 = [1, 2, 3]; ``` ``` const arr4: number[] = [1, 2, 3]; ``` 泛型 ``` const arr5: Array<number> = [1, 2, 3]; ``` ## Tuple 類似於array但是比array條件更為嚴格 以下的範例表示tu這個tuple內有三個資料,依序為number string boolean,如果順序不同,或是多一個資料都會報錯。 ``` const tu: [number, string, boolean] = [135, "string", true]; ``` ### 二維陣列 以下的程式碼表示陣列中的陣列順序維number,boolean ``` const tu2: [number,boolean][] = [[158,false],[456,true],[589,false]] ``` ## TypeScript 關於物件的宣告 ### TypeScript物件的特性與Array、純值相同 與Array、純值相同,只要一開始所賦值的資料類別與物件的屬性不同就會報錯。 範例如下, ``` const obj = { name:"Jack", age:26}; obj.age ="45"; ``` 這個時候obj的屬性age已經預設number所以賦值為string會報錯 ![](https://i.imgur.com/JYr59Ft.png) 另外也可以直接定義物件的屬性資料類別,不過這麼做除了只能用let宣告物件外另外只要屬性一多程式碼就會變得很不好閱讀,會有type與interface處理這個問題 ``` let obj2:{ name:string, age:number } ; obj2 = { name:"Jack", age:39 } ``` ### 物件內的value是null與undefined的時候 把obj.age賦值為null或是undefined的時候不會報錯 ``` const obj = { name:"Jack", age:26}; obj.age =undefined; ``` 如下圖沒有紅色標記或是報錯 ![](https://i.imgur.com/eFSUyhY.png) #### strictNullChecks 要如何處理物件內的值被寫入null或是undefined時不會報錯的情況呢? 在tsconfig.json中加入 ``` "strictNullChecks":true, ``` 把物件的age賦值為undefined時報錯 ``` const obj = { name:"Jack", age:26}; obj.age = undefined; ``` ![](https://i.imgur.com/bz0vafr.png) #### 物件的屬性加上?則變為可以undefined 在物件的age屬性加上? ``` let obj2:{ name:string, age?:number } ; obj2 = { name:"Jack", } ``` 沒有age也不會報錯 ## unknown unknow是什麼? 可以先理解為比較安全的any 可以看到下面的範例加上unknown時與any一樣,把myname賦值為其他類型的資料時不會報錯 ``` let myname: unknown = "Jack"; myname = 123 ``` ## 斷言 as 直接指定資料為某種類別,範例如下 ``` let myname: unknown = "Jack"; let myname2 = myname as string; ``` 但時as的用處是告訴TS收到資料時的資料類別。 下圖是範例程式碼的api會收到的資料 ![](https://i.imgur.com/UquyWzB.png) ``` async function getData(){ const res = await fetch('https://jsonplaceholder.typicode.com/todos/1') const data = await res.json() as { userId:number, id:number, title:string, completed:boolean} console.log(data) } ``` 可以從下圖中看到data內的資料類別,就是透過as告訴TS ![](https://i.imgur.com/ZCSHsxq.png) ## any與unknown的區別 區別就在於使用any時不會提醒你要不要判斷型別,使用unknown會。 使用any時的程式碼 ``` const statusLive = false; let statusName: any = ""; if(statusLive){ statusName = "myLive"; } else { statusName = null; } const result = statusName.split(""); console.log(result); ``` 會如下圖到了執行的時候才知道statusName.split("")出錯了 ![](https://i.imgur.com/5pYc0IG.png) 換成unknown ``` const statusLive = false; let statusName: unknown = ""; if(statusLive){ statusName = "myLive"; } else { statusName = null; } const result = statusName.split(""); console.log(result); ``` 會如下圖在程式碼未執行前題是錯誤 ![](https://i.imgur.com/BuiY3i3.png) ## union 什麼是union,簡單的來說就是資料只能由幾種類型的純值所組成。 在下方範例中info就是string與number的union dataArray就是string與boolean的union ``` let info: string | number = "Jack"; info = 1234; const dataArray: (string| boolean)[] = ["jack", false]; ``` ## never TS提示變數的狀態。 在下方的程式碼之中,變數sample,不可能會變成字串所以TS會提示變數sample變成never如範例下的圖片所示 ``` let sample: number | string ; sample = "Hello"; sample = 456; if(typeof sample === "string") { console.log(sample); } ``` ![](https://i.imgur.com/IIWLGQy.png) ## 強制斷言 在某些情況下變數的類型會改變,但是TypsScript不允許直接使用as改變類別,會報錯。 ``` const dataNum = 123; const dataNum2 = dataNum as string ``` ![](https://i.imgur.com/g4hQXFn.png) 所以要先把類型變成unknown 範例如下 ``` const dataNum = 123; // ...執行了某些步驟後dataNum2變成string const dataNum2 = dataNum as unknown as string ```