cover

概念圖

一句話:搞懂 TypeScript 基本型別,就是搞懂「這個變數到底能放什麼」。

先講結論

TypeScript 的基本型別就那幾個:stringnumberboolean,加上 nullundefinedvoidanyunknownnever。聽起來很多?其實日常開發 90% 的時間你只會用到前三個加上聯合型別。但剩下那 10% 如果搞不清楚,踩到坑會很痛。

三大天王:string / number / boolean

// 明確宣告
let name: string = "John";
let age: number = 25;
let isActive: boolean = true;
 
// TypeScript 其實夠聰明,會自己推論
let city = "Taipei";  // 自動推論為 string,不用你多寫

這三個沒什麼好說的,你在 JavaScript 裡怎麼用,TypeScript 裡就怎麼用。唯一的差別是現在有人幫你顧著,不會讓你把 "25" 塞進一個 number 變數裡。

那些「其他的」型別

這邊才是重點。你遲早會遇到以下幾個:

// null 和 undefined:都是「沒有值」,但語義不同
let nothing: null = null;           // 你主動說「這裡沒東西」
let notAssigned: undefined = undefined; // 系統說「還沒給值」
 
// void:function 不回傳東西時用
function logMessage(msg: string): void {
  console.log(msg);
}
 
// any:跟 TypeScript 說「別管我」(能不用就不用)
let anything: any = "hello";
anything = 42;  // 不會報錯,但你也回到了 JS 的蠻荒時代
 
// unknown:比 any 安全的「我不確定是啥」
let mystery: unknown = "could be anything";
// mystery.toUpperCase();  // 報錯!你得先確認型別
if (typeof mystery === "string") {
  mystery.toUpperCase();  // 這樣才行
}
 
// never:「這種事不可能發生」
function throwError(msg: string): never {
  throw new Error(msg);  // 永遠不會正常 return
}

anyunknown 的差別是什麼?想像 any 是「我不在乎」,unknown 是「我目前不知道,但我會先查清楚再用」。後者明顯比較負責任,對吧?

陣列和聯合型別

// 陣列兩種寫法,看你習慣哪個
let fruits: string[] = ["apple", "banana"];
let numbers: Array<number> = [1, 2, 3];
 
// 聯合型別:一個變數可以是好幾種型別
let id: string | number;
id = "abc";  // OK
id = 123;    // 也 OK
 
// 幫聯合型別取名字,之後重複用
type UserID = string | number;
let myId: UserID = "user-001";

常見踩坑

別用大寫的 StringNumberBoolean。那些是 JavaScript 的包裝物件,不是原始型別。TypeScript 世界裡永遠用小寫。用大寫的話,TypeScript 不會罵你,但 code review 的同事會。

少用 any。用了 any 就是跟 TypeScript 說「你可以下班了」,然後你自己加班 debug。真的不確定型別,用 unknown

nullundefined 不一樣null 是你主動給的「空」,undefined 是系統的「還沒填」。開了 strictNullChecks 之後,這兩個不能隨便互換,TypeScript 會盯得很緊。


型別系統聽起來像是多了一個管家在碎唸,但等你第一次因為它在 compile time 就抓到 bug 的時候,你會想給它加薪。

延伸閱讀