TypeScript 是什麼?為什麼要用?
TypeScript 是 JavaScript 的超集,為 JavaScript 加上靜態類型。本篇將帶你了解為什麼越來越多團隊選擇 TypeScript。
一、 JavaScript 的痛點
1.1 類型不明確
javascript
// 這個函式接收什麼?回傳什麼?
function calculate(a, b, operation) {
if (operation === 'add') return a + b
if (operation === 'subtract') return a - b
// ...
}
// 呼叫時容易出錯
calculate('10', 5, 'add') // '105' 字串拼接!
calculate(10, 5, 'ad') // undefined 打錯字沒有提示!1.2 重構困難
javascript
// 假設有一個使用者物件
const user = {
name: 'John',
email: 'john@example.com',
}
// 專案中有 100 處使用 user.email
// 現在要把 email 改成 mail...
// 你敢保證全部改對嗎?1.3 IDE 支援有限
javascript
// 沒有類型,IDE 無法提供:
// - 自動完成
// - 參數提示
// - 錯誤檢查二、 TypeScript 解決了什麼?
2.1 編譯時期錯誤檢查
typescript
function calculate(
a: number,
b: number,
operation: 'add' | 'subtract'
): number {
if (operation === 'add') return a + b
if (operation === 'subtract') return a - b
return 0
}
// 編譯錯誤!
calculate('10', 5, 'add') // 類型 'string' 不可指派給 'number'
calculate(10, 5, 'ad') // 類型 'ad' 不可指派給 'add' | 'subtract'
// 正確
calculate(10, 5, 'add') // 152.2 安全重構
typescript
interface User {
name: string
email: string // 改名為 mail 時,所有使用處都會報錯
}
const user: User = {
name: 'John',
email: 'john@example.com',
}
// 改名 email → mail 後,TypeScript 會標記所有需要修改的地方2.3 強大的 IDE 支援
typescript
// 有了類型,IDE 可以提供:
// 智能自動完成
// 參數提示
// 即時錯誤檢查
// 跳轉到定義
// 重構工具三、 TypeScript vs JavaScript
3.1 基本比較
| 特性 | JavaScript | TypeScript |
|---|---|---|
| 類型系統 | 動態類型 | 靜態類型 |
| 錯誤檢查 | 執行時期 | 編譯時期 |
| IDE 支援 | 有限 | 強大 |
| 學習曲線 | 低 | 中 |
| 程式碼量 | 較少 | 較多 |
3.2 靜態類型 vs 動態類型
重點:TypeScript 把錯誤從「執行時期」提前到「編譯時期」!
四、 TypeScript 編譯流程
4.1 基本流程
4.2 類型只存在於編譯時期
typescript
// TypeScript 程式碼
interface User {
name: string
age: number
}
function greet(user: User): string {
return `Hello, ${user.name}!`
}
const john: User = { name: 'John', age: 30 }
console.log(greet(john))編譯後的 JavaScript:
javascript
// 類型完全消失!
function greet(user) {
return `Hello, ${user.name}!`
}
const john = { name: 'John', age: 30 }
console.log(greet(john))NOTE
TypeScript 的類型只在編譯時期存在,不會影響執行時期效能。
五、 TypeScript 的優勢
5.1 提早發現錯誤
typescript
// 常見錯誤類型
const user = { name: 'John' }
console.log(user.naem) // 屬性 'naem' 不存在,你是不是要說 'name'?
function double(n: number) {
return n * 2
}
double('5') // 類型 'string' 不可指派給 'number'5.2 更好的程式碼文件
typescript
// 類型就是最好的文件
interface CreateUserInput {
name: string
email: string
password: string
age?: number // 可選
}
function createUser(input: CreateUserInput): Promise<User> {
// 實作...
}
// 看一眼就知道:
// - 需要什麼參數
// - 哪些是必填、哪些是可選
// - 會回傳什麼5.3 團隊協作更順暢
typescript
// API 介面定義清楚
interface ApiResponse<T> {
success: boolean
data: T
error?: string
}
// 任何人都知道怎麼使用
async function fetchUsers(): Promise<ApiResponse<User[]>> {
// ...
}六、 何時該用 TypeScript?
6.1 推薦使用
| 場景 | 原因 |
|---|---|
| 中大型專案 | 類型幫助維護 |
| 團隊協作 | 介面定義清楚 |
| 長期維護 | 重構更安全 |
| 複雜商業邏輯 | 減少 Bug |
6.2 可以考慮
| 場景 | 說明 |
|---|---|
| 小型專案 | 成本效益考量 |
| 快速原型 | 靈活性優先 |
| 獨立開發 | 視個人習慣 |
七、 常見迷思
迷思 1:TypeScript 很難學
事實:如果你會 JavaScript,可以逐步加入類型,不需要一次學會所有進階功能。
迷思 2:TypeScript 會讓程式碼變慢
事實:類型只在編譯時期存在,不影響執行效能。
迷思 3:TypeScript 要寫很多額外的程式碼
事實:TypeScript 有強大的類型推論,很多時候不需要明確標註。
typescript
// 不需要明確標註,TypeScript 會推論
const name = 'John' // 推論為 string
const age = 30 // 推論為 number
const users = ['a', 'b'] // 推論為 string[]總結
| 面向 | JavaScript | TypeScript |
|---|---|---|
| 類型 | 動態 | 靜態 |
| 錯誤發現 | 執行時 | 編譯時 |
| IDE 支援 | 有限 | 強大 |
| 重構 | 風險高 | 安全 |
| 學習成本 | 低 | 中 |
| 適合 | 小專案 | 中大專案 |
> **一句話總結**:TypeScript = JavaScript + 類型系統 = 更安全的程式碼
進階挑戰
找出以下 JavaScript 程式碼中的潛在問題,思考 TypeScript 如何幫助避免:
javascript
function getFullName(user) {
return user.firstName + ' ' + user.lastName
}
const user1 = { firstName: 'John', lastName: 'Doe' }
const user2 = { name: 'Jane' }
console.log(getFullName(user1))
console.log(getFullName(user2)) // 會發生什麼?