本文 AI 產出,尚未審核

TypeScript 基本型別(Primitive Types)

string、number、boolean


簡介

在任何程式語言中,**型別(type)**都是最基礎、也是最重要的概念之一。它不僅決定了變數能存什麼樣的資料,還直接影響程式的可讀性、維護成本與執行效能。TypeScript 作為 JavaScript 的超集合,透過靜態型別檢查,讓開發者在編譯階段就能捕捉到許多潛在的錯誤,提升開發效率與程式品質。

本單元聚焦於 三個最常使用的原始型別stringnumberboolean。它們分別代表文字、數值與布林值,幾乎所有的業務邏輯都會與這三種型別打交道。了解它們在 TypeScript 中的行為、限制與最佳實踐,能讓你寫出更安全、更具表達力的程式碼。


核心概念

1. string – 文字資料

在 TypeScript 中,string 用來表示一串 Unicode 文字。與 JavaScript 相同,字串可以使用單引號 ('...')、雙引號 ("...") 或是 ES6 引入的 模板字面值(template literals)`...`)來宣告。

1.1 基本宣告與型別推斷

let greeting: string = 'Hello, TypeScript!';   // 明確指定型別
let name = "Alice";                           // 型別推斷為 string

1.2 模板字面值與表達式插值

模板字面值允許在字串中直接嵌入變數或運算式,寫起來更直觀。

const age = 28;
const intro = `我叫 ${name},今年 ${age} 歲。`; // ${} 內可寫任意表達式

1.3 常用字串方法

TypeScript 繼承了 JavaScript 的所有字串方法,且在編譯階段會提供完整的型別資訊。

// 判斷字串是否以特定前綴開頭
if (greeting.startsWith('Hello')) {
  console.log('問候語以 Hello 開頭');
}

// 取出子字串
const sub = greeting.slice(0, 5); // "Hello"

1.4 字串聯集型別(String Literal Types)

TypeScript 允許把字串寫成 字面值型別,用於限制變數只能接受特定的文字。

type Direction = 'up' | 'down' | 'left' | 'right';
let move: Direction = 'up';   // 正確
// move = 'forward';          // 編譯錯誤:型別不符合

2. number – 數值資料

number 在 TypeScript 中代表 IEEE 754 雙精度浮點數,同時支援整數、浮點數、十六進位、二進位與八進位寫法。沒有 intfloat 等子型別,所有數字皆屬於同一型別。

2.1 基本宣告

let count: number = 42;          // 整數
let price = 99.95;               // 浮點數(型別推斷)
let hex = 0xFF;                  // 十六進位
let bin = 0b1010;                // 二進位
let oct = 0o755;                 // 八進位

2.2 數字運算

const radius = 5;
const area = Math.PI * radius ** 2; // ** 為次方運算子
console.log(`圓面積為 ${area.toFixed(2)}`);

2.3 NaNInfinity 與型別安全

NaN(Not a Number)與 Infinity 也是 number 型別的合法值,但在實務開發中往往需要特別處理。

function safeDivide(a: number, b: number): number {
  if (b === 0) {
    return Infinity; // 或拋出例外
  }
  return a / b;
}

const result = safeDivide(10, 0);
if (!Number.isFinite(result)) {
  console.warn('除以零產生無限大');
}

2.4 數字字面值型別(Numeric Literal Types)

類似字串字面值型別,數字也可以限定為特定值的聯集。

type Dice = 1 | 2 | 3 | 4 | 5 | 6;
function roll(): Dice {
  return (Math.floor(Math.random() * 6) + 1) as Dice;
}

3. boolean – 布林值

boolean 只有兩個可能的值:truefalse。在 TypeScript 中,布林值常用於條件判斷、流程控制與型別守衛(type guard)。

3.1 基本宣告

let isActive: boolean = true;
let isDone = false; // 型別推斷為 boolean

3.2 與條件式結合

if (isActive && !isDone) {
  console.log('任務尚未完成且仍在執行');
}

3.3 真值(truthy)與偽值(falsy)的差異

雖然 JavaScript 允許使用任何「真值」或「偽值」在條件式中,TypeScript 建議仍以 boolean 為主,以避免隱性類型轉換帶來的錯誤。

let count = 0;
if (count) {          // 這裡會被視為偽值,但型別是 number
  // ...不建議這樣寫
}

// 正確寫法
let hasItems: boolean = count > 0;
if (hasItems) {
  // ...
}

3.4 布林字面值型別

type YesNo = true | false;
let answer: YesNo = true; // 明確指定

程式碼範例(實用範例)

以下示範 5 個在日常開發中常見且實用的範例,涵蓋 stringnumberboolean 的互動與型別安全。

範例 1:表單驗證(字串與布林)

type ValidationResult = {
  valid: boolean;
  message: string;
};

function validateEmail(email: string): ValidationResult {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  const isValid = emailRegex.test(email);
  return {
    valid: isValid,
    message: isValid ? 'Email 格式正確' : '請輸入有效的 Email',
  };
}

// 使用
const userEmail = 'alice@example.com';
const result = validateEmail(userEmail);
if (!result.valid) {
  console.error(result.message);
}

重點validbooleanmessagestring,型別明確讓錯誤訊息更易追蹤。

範例 2:計算折扣(數字與字串)

function calculateDiscount(price: number, rate: number): string {
  const discounted = price * (1 - rate);
  // 使用 toFixed 固定小數點兩位,並加上貨幣符號
  return `$${discounted.toFixed(2)}`;
}

// 呼叫
console.log(calculateDiscount(1200, 0.15)); // $1020.00

說明pricerate 必須是 number,返回值是格式化後的 string,避免在 UI 層再次轉型。

範例 3:旗標(Flag)控制流程

type FeatureToggle = {
  darkMode: boolean;
  betaAccess: boolean;
};

function renderUI(toggles: FeatureToggle) {
  const theme = toggles.darkMode ? 'dark' : 'light';
  console.log(`使用 ${theme} 主題`);

  if (toggles.betaAccess) {
    console.log('顯示 Beta 功能區塊');
  }
}

// 範例
renderUI({ darkMode: true, betaAccess: false });

技巧:把多個布林值集中在一個物件中,讓程式碼更具可讀性與擴充性。

範例 4:枚舉(Enum)結合字串字面值

enum LogLevel {
  INFO = 'info',
  WARN = 'warn',
  ERROR = 'error',
}

function log(message: string, level: LogLevel = LogLevel.INFO): void {
  console[level](`[${level.toUpperCase()}] ${message}`);
}

// 使用
log('系統啟動完成');                     // 預設 INFO
log('磁碟空間不足', LogLevel.WARN);
log('未捕獲的例外', LogLevel.ERROR);

說明LogLevel 以字串值實作,配合 enum 提供自動補全與型別安全。

範例 5:型別守衛(Type Guard)範例

function formatValue(value: string | number | boolean): string {
  if (typeof value === 'string') {
    return `"${value}"`;               // 文字加上引號
  }
  if (typeof value === 'number') {
    return value.toFixed(2);           // 數字保留兩位小數
  }
  // 此時 value 必為 boolean
  return value ? '是' : '否';
}

// 測試
console.log(formatValue('TS'));   // "TS"
console.log(formatValue(3.1415)); // 3.14
console.log(formatValue(false));  // 否

重點:利用 typeof 進行型別守衛,讓每個分支的 value 變成確定的型別,避免不必要的型別斷言。


常見陷阱與最佳實踐

陷阱 說明 建議的最佳實踐
隱式 any 未宣告型別或未啟用 noImplicitAny,導致變數被推斷為 any,失去型別保護。 tsconfig.json 中開啟 noImplicitAny,並盡量使用顯式型別或型別推斷。
字串與數字的隱式轉換 JavaScript 會自動把字串與數字互相轉換,可能產生意外結果。 在 TypeScript 中避免使用 ==,改用 ===;必要時手動轉型(Number(str)String(num))。
NaNInfinity 的誤用 許多運算會產生 NaN,但 NaN !== NaN,容易導致判斷失效。 使用 Number.isNaN(value)Number.isFinite(value) 進行檢查。
布林值的偽值陷阱 0''nullundefined 當作 false 使用,會讓程式行為不一致。 明確使用 boolean 型別,或在條件式前先做類型檢查 (value === true)。
字面值型別過度使用 為每個字串/數字建立字面值型別,會讓型別宣告過於繁雜。 僅在需要限制取值範圍(如 API 參數、狀態機)時使用;否則使用普通 string/number

其他最佳實踐

  1. 使用 const 取代 let:對於不會重新指派的變數,使用 const 能讓編譯器更好地推斷出 字面值型別(例如 'up' 而非 string)。
  2. 啟用嚴格模式"strict": true 能自動開啟多項檢查,包括 strictNullChecks,避免 null/undefined 帶來的意外。
  3. 盡量避免 any:若真的需要暫時使用,可改用 unknown,在使用前必須先做型別檢查,保持安全性。
  4. 利用 as const:對於陣列或物件的常量,使用 as const 讓其屬性變成 只讀字面值型別,減少誤寫。
  5. 保持一致的字串引號風格:團隊可統一使用單引號或雙引號,或是根據 ESLint 規則自動格式化。

實際應用場景

場景 為何需要嚴格的原始型別 範例
API 請求/回應 後端資料結構通常固定,錯誤的型別會導致 UI 無法正確呈現。 定義 interface User { id: number; name: string; isActive: boolean; },在 fetch 後使用 as User 前先做型別守衛。
表單驗證 使用者輸入的文字、數字、勾選框分別對應 stringnumberboolean,若混用會產生驗證錯誤。 參考「範例 1」的 validateEmail,把每個欄位的型別寫清楚。
狀態機(State Machine) 狀態往往是有限集合(如 `'idle' 'loading'
計算與統計 金額、比率等必須是 number,避免文字相加造成錯誤。 參考「範例 2」的價格折扣計算。
功能開關(Feature Flag) 多個布林旗標控制功能顯示與行為,若誤把字串 'true' 當布林,會導致邏輯錯亂。 參考「範例 3」的 FeatureToggle 物件。

總結

  • stringnumberboolean 是 TypeScript 中最基礎、最常見的三種原始型別,掌握它們的宣告、操作方式與型別安全是寫好任何程式的根基。
  • 透過 字面值型別模板字面值型別守衛 等語法,TypeScript 能在編譯階段即捕捉錯誤,提升開發效率與程式可靠度。
  • 在實務開發中,避免隱式轉型適時使用嚴格模式明確標註型別,是防止常見陷阱的關鍵。
  • 只要養成 以型別為中心的思考方式,在 API、表單、狀態管理與業務邏輯等場景下,都能寫出乾淨、易維護的 TypeScript 程式碼。

祝你在 TypeScript 的旅程中,從基礎型別踏出堅實的第一步,開發出更安全、更可靠的前端與全端應用! 🚀