跳至主要內容
Skip to content

TypeScript 基礎類型完全解析

類型是 TypeScript 的核心。本篇將帶你認識所有基礎類型,打好類型系統的根基。


一、 原始類型(Primitive Types)

1.1 string

typescript
// 明確標註
const name: string = 'John'

// 類型推論(推薦)
const greeting = 'Hello' // 自動推論為 string

// 模板字串
const message = `${greeting}, ${name}!` // string

1.2 number

typescript
const age: number = 30
const price: number = 99.99
const hex: number = 0xff
const binary: number = 0b1010
const octal: number = 0o744

// 類型推論
const count = 100 // number

1.3 boolean

typescript
const isActive: boolean = true
const hasPermission: boolean = false

// 類型推論
const isValid = true // boolean

1.4 symbol

typescript
const sym1: symbol = Symbol('key')
const sym2: symbol = Symbol('key')

console.log(sym1 === sym2) // false,每個 Symbol 都是唯一的

1.5 bigint

typescript
const bigNumber: bigint = 9007199254740991n
const anotherBig: bigint = BigInt(100)

// 注意:bigint 和 number 不能混用
const num: number = 10
// const result = bigNumber + num  // 錯誤!

二、 特殊類型

2.1 null 和 undefined

typescript
const nullValue: null = null
const undefinedValue: undefined = undefined

// 通常搭配聯合類型使用
let name: string | null = null
name = 'John'

let age: number | undefined = undefined
age = 30

2.2 void

函式沒有回傳值時使用:

typescript
function log(message: string): void {
  console.log(message)
  // 沒有 return,或 return undefined
}

// 箭頭函式
const logArrow = (message: string): void => {
  console.log(message)
}

2.3 any

「逃生艙口」——關閉類型檢查:

typescript
let anything: any = 'hello'
anything = 42
anything = { name: 'John' }
anything.foo.bar // 不會報錯,但執行時可能出錯!

//  盡量避免使用 any

2.4 unknown

any 更安全的「未知類型」:

typescript
let value: unknown = 'hello'
value = 42
value = { name: 'John' }

// 不能直接使用
// const length = value.length  // 錯誤!

// 必須先收窄類型
if (typeof value === 'string') {
  console.log(value.length) // OK
}

2.5 never

表示「永遠不會發生」的類型:

typescript
// 永遠拋出錯誤
function throwError(message: string): never {
  throw new Error(message)
}

// 無限迴圈
function infiniteLoop(): never {
  while (true) {}
}

// 用於窮盡檢查
type Color = 'red' | 'blue'

function handleColor(color: Color) {
  switch (color) {
    case 'red':
      return '紅色'
    case 'blue':
      return '藍色'
    default:
      const _exhaustive: never = color // 確保所有情況都處理了
      return _exhaustive
  }
}

三、 陣列類型

3.1 基本語法

typescript
// 語法一:T[]
const numbers: number[] = [1, 2, 3]
const names: string[] = ['John', 'Jane']

// 語法二:Array<T>
const numbers2: Array<number> = [1, 2, 3]
const names2: Array<string> = ['John', 'Jane']

// 推薦使用 T[] 語法,更簡潔

3.2 多維陣列

typescript
// 二維陣列
const matrix: number[][] = [
  [1, 2, 3],
  [4, 5, 6],
]

// 三維陣列
const cube: number[][][] = [
  [
    [1, 2],
    [3, 4],
  ],
  [
    [5, 6],
    [7, 8],
  ],
]

3.3 混合類型陣列

typescript
// 聯合類型陣列
const mixed: (string | number)[] = ['hello', 42, 'world']

// 注意括號位置
const wrong: string | number[] = 'hello' // string 或 number[]
const right: (string | number)[] = ['hello', 42] // (string | number) 的陣列

四、 元組(Tuple)

4.1 基本元組

typescript
// 固定長度和類型的陣列
const tuple: [string, number] = ['hello', 42]

// 存取元素
const first = tuple[0] // string
const second = tuple[1] // number

// 越界存取
// const third = tuple[2]  // 錯誤!

4.2 可選元素

typescript
// 第三個元素可選
const tuple: [string, number, boolean?] = ['hello', 42]

// 也可以是
const tuple2: [string, number, boolean?] = ['hello', 42, true]

4.3 具名元組

typescript
// 更清楚的語義
type Coordinate = [x: number, y: number]
const point: Coordinate = [10, 20]

// 函式回傳
function useState<T>(initial: T): [value: T, setValue: (v: T) => void] {
  let value = initial
  return [
    value,
    (v) => {
      value = v
    },
  ]
}

4.4 唯讀元組

typescript
const tuple: readonly [string, number] = ['hello', 42]
// tuple[0] = 'world'  // 錯誤!

五、 類型推論

5.1 基本推論

TypeScript 會自動推論類型:

typescript
// 明確推論
const name = 'John' // string
const age = 30 // number
const isActive = true // boolean
const numbers = [1, 2, 3] // number[]

// let 和 const 的差異
const constName = 'John' // 類型是 'John'(字面量類型)
let letName = 'John' // 類型是 string

5.2 何時需要明確標註?

typescript
// 1. 無法推論時
let name: string // 稍後賦值

// 2. 空陣列
const items: string[] = [] // 不標註會是 never[]

// 3. 函式參數
function greet(name: string) {
  // 必須標註
  return `Hello, ${name}!`
}

// 4. 複雜物件
interface User {
  name: string
  age: number
}
const user: User = { name: 'John', age: 30 }

5.3 最佳實踐

typescript
// 讓 TypeScript 推論
const name = 'John'
const users = ['John', 'Jane']

// 必要時才標註
function createUser(name: string, age: number) {
  return { name, age } // 回傳值自動推論
}

// 過度標註(冗餘)
const name: string = 'John' // 多餘

六、 類型比較表

類型說明範例
string字串'hello'
number數字42, 3.14
boolean布林true, false
null空值null
undefined未定義undefined
void無回傳函式
any任意(不檢查)避免使用
unknown未知(安全)需收窄
never不可能錯誤、無限迴圈
T[]陣列number[]
[T, U]元組[string, number]

總結

> **記憶技巧**:

  • any:我不管類型
  • unknown:我不知道類型,要先檢查
  • never:這不可能發生

進階挑戰

為以下變數加上正確的類型:

typescript
// 練習:加上類型標註
const username = ___
const userAge = ___
const isAdmin = ___
const scores = ___
const userInfo = ___ // 提示:元組 [姓名, 年齡, 是否管理員]

// 初始值
username = 'Alice'
userAge = 25
isAdmin = false
scores = [95, 87, 92]
userInfo = ['Alice', 25, false]

延伸閱讀與資源