iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

Hello TypeScript 菜鳥系列 第 5

Day 4. TypeScript 基本型別

  • 分享至 

  • xImage
  •  

Day 4開始要認識TypeScript的型別系統。

TypeScript擴充了JavaScript既有的型別系統,包含基本型別(primitive type)和參考型別(reference type),相較於大都與JavaScript相同的基本型別,TypeScript提供更多好用的參考型別,像是interfaceenumtuple

個人覺得比較值得學習的是參考型別,畢竟實戰中碰到最多的是這類型別,而且也相對複雜,所以今天這篇算是藉著學習TypeScript宣告有型別變數的用法來複習JavaScript型別,希望這幾天不會花太多篇幅在基本型別(汗)。


number

TypeScript的number型別可以接受十進位(decimal)、二進位(binary)、八進位(octal)和十六進位(hexadecimal)的值,唯獨bigint值還是得指定是bigint型別。

除了十進位可直接輸入十進位值,其他進位的值須在值的開頭加上識別字符,

  • 二進位加上0b0B
  • 八進位值開頭要加上0o0O
  • 十六進位值的開頭加上0x0x

number型別變數範例

let decimal: number = 13;
let binary: number = 0b1101;    // 或 0B1101
let octal: number = 0o15;       // 或 0O15
let hexadecimal: number = 0xB;  // 或 0XB

bigint

JavaScript從ES2020開始支援bigint型別,因此TypeScript同樣也有提供bigint型別。

bigint是指超過 2^53^-1 的數值,其值最後面要加上n才是bigint型別的數值,如:999999999999999999n

bigint型別變數範例:

let big: bigint = 999999999999999999n;

string

基本上string型別語法都跟JavaScript一樣,支援雙引號 "、單引號 ' 和反引號 `

string型別範例:

let dbstr: string = "Hello";
let singstr: string = "World";
let backstr: string = ` TypeScript
is
Fun
`;

boolean

boolean型別跟JavaScript一樣只允許truefalse值,其用法也相同:

let real: boolean = true;
let fake: boolean = false;

real = false;    // ok

Symbol

Symbol基本型別用法也與JavaScript相同,是用 Symbol() 來宣告一個Symbol型別變數,例如:

let firstname = "name";
let lastname = "name";

console.log(firstname === lastname);    // false

Symbol平常比較少用到,不過原則上就是用來 創造型別 ,所以像上面兩個 Symbol 變數雖然都儲存相同的 "name",但事實上是代表兩個不同型別,也就是兩種不同的東西,所以在作相等判斷時,永遠都是 return false

undefined、null

TypeScript同樣也有undefined和null,但這兩種型別平常在寫JavaScript的時候造成不少麻煩,所以TypeScript有提供編譯組態和運算子(operator)來處理這兩種型別。

strictNullCheck
tsconfig檔案有提供 strictNullCheck 選項來嚴格限制是否要嚴格限制可能出現這兩種型別的狀況

若設定此選項為 true 的時候,必須對可能出現 undefinednull 的情況作處理;若沒有適當處理,TypeScript編譯器可能會出現以下編譯錯誤:

error TS2531: Object is possibly 'null'.

基本上官方文件是建議可勾選 true 來避免值為 undefined 或 null 時可能造成的程式錯誤。

Non-null type assertion operator !
某些情況下可能會想忽略以上編譯器出現的錯誤,官方文件說明 ! 代表著「告訴編譯器,你斷言(assert)這個值不會是null或undefined的狀況」,看起來有點抽象,來看一個使用!的簡單例子。

假設hello1和hello2允許不傳入 People、可能是undefined且只顯示 hello 的狀況,此時hello1函式的people因為是undefined也就沒有name屬性,所以編譯器就會出現編譯錯誤:

interface People{
    name: string,
}


function hello1(people: People | undefined){
    console.log(`Hello ${people.name}`) // compile error
}

function hello2(people: People | undefined){
    console.log(`Hello ${people!.name}`) // great
}

若是想允許只出現 hello 的狀況發生,可在 people.name 的 people 後面加上 ! ,如hello2函式寫法,避免編譯錯誤。

如果是以我自己之前寫React時的狀況為例,有時候我會先把component寫好,如果有資料送進component才會依據送進來的資料改變其狀態並渲染,但有時候某些資料是允許不必傳入某些component,這時就有可能會出現像上面範例一樣的錯誤,這時就可以利用 ! 讓程式碼通過型別的檢查。


TypeScript除了以上跟JavaScript一樣的型別,也有提供anyvoidneverunknown 等型別,明天就會來了解這三個型別的意思。

另外,以上都是明確宣告變數型別的範例,這個明確宣告型別的行為稱為 type annotation (或是 type signature);不過,如果變數使用的情境比較單純,TypeScript也能從變數初始值自行推導出變數的型別,TypeScript compiler自行推導變數型別的行為則稱為type inference

最後再看一次Day 1舉的極簡例子來看type annotation和type inference的差別:

/* Type annotation */
let x: number = 10;
x = "20";    // error ( x is number type)


/* Type inference */
let y = "15";
y = 22;    // error (y is string type)


參考資料
TypeScript Tutorial
TypeScript Tutorial: A step-by-step guide to learn TypeScript
Non-null assertion operator


上一篇
Day 3. TypeScript環境設置:編譯組態設定(tsconfig)
下一篇
Day 5. TypeScript內建的基本型別:any、unknown、void、never
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言