TypeScript 基礎類型完全解析
類型是 TypeScript 的核心。本篇將帶你認識所有基礎類型,打好類型系統的根基。
一、 原始類型(Primitive Types)
1.1 string
typescript
// 明確標註
const name: string = 'John'
// 類型推論(推薦)
const greeting = 'Hello' // 自動推論為 string
// 模板字串
const message = `${greeting}, ${name}!` // string1.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 // number1.3 boolean
typescript
const isActive: boolean = true
const hasPermission: boolean = false
// 類型推論
const isValid = true // boolean1.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 = 302.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 // 不會報錯,但執行時可能出錯!
// 盡量避免使用 any2.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' // 類型是 string5.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]