

JavaScript 的型別問題
JavaScript 是動態型別語言,在操作各種型別時會自動做隱式轉換:
// JavaScript 的隱式轉換
"5" + 3 // "53" (字串)
"5" - 3 // 2 (數字)
true + true // 2
[] + {} // "[object Object]"這些行為在個人開發時可能問題不大,但在團隊協作或前後端介接時,常常會造成難以追蹤的 bug。
一個真實的 Bug 場景
想像一下,你在串接一個使用者 API,後端回傳的資料長這樣:
// 你以為 API 回傳的是這樣
const user = { name: "Alice", age: 25 };
// 但某天後端改了欄位,多了巢狀結構
const user = { name: "Alice", profile: { age: 25 } };
// 你的程式碼還在用舊的寫法
console.log(user.age); // undefined,不會報錯,但畫面壞了用 JavaScript 的話,這段程式碼不會在開發時報任何錯。直到上線後使用者回報「頁面顯示 undefined」,你才會發現問題。但如果用 TypeScript 呢?
// TypeScript 版本:定義好型別
interface User {
name: string;
profile: { age: number };
}
const user: User = await fetchUser();
console.log(user.age);
// ^^^ 編譯錯誤!Property 'age' does not exist on type 'User'還沒跑程式就抓到了,對吧?這就是 TypeScript 最大的價值。
JS vs TS 的錯誤抓取流程
flowchart LR A[JavaScript 程式碼] --> B[直接執行] B --> C[Runtime Error 💥] C --> D[使用者看到 bug] E[TypeScript 程式碼] --> F[編譯器檢查] F --> G[Compile-time Error ⚠️] G --> H[開發者修正] H --> F F --> I[安全的 JS 程式碼] I --> J[正常執行 ✅]
簡單來說,TypeScript 把「使用者幫你找 bug」變成了「編譯器幫你找 bug」。
TypeScript 解決了什麼?
- 編譯時期型別檢查:在程式執行前就能發現型別錯誤
- 更好的 IDE 支援:自動補全、重構、跳轉定義
- 自我文件化:型別定義本身就是文件
- 減少執行時錯誤:避免
undefined is not a function等常見錯誤
常見的反對聲音
「太麻煩了,要多寫好多程式碼」
確實,TypeScript 需要多寫型別定義。但你有沒有想過,那些省下來的 debug 時間,遠比多打幾個型別還要多?而且 TypeScript 有很強的型別推論,很多時候你根本不需要手動寫型別。
「學習曲線太高」
基礎的 TypeScript 其實跟 JavaScript 差不多,你只是多學幾個型別註解而已。進階功能(泛型、條件型別等等)可以之後再慢慢學,不影響你馬上開始用。
「小專案不需要」
小專案可能不需要,但小專案有時候會長大,對吧?一開始就用 TypeScript,比之後要把整個專案從 JS 遷移到 TS 輕鬆太多了。
什麼時候不需要 TypeScript?
話說回來,TypeScript 也不是所有場景都適合:
- 一次性的小腳本:寫個快速的資料處理 script,用 JS 就好
- 快速原型驗證:在 hackathon 或 POC 階段,速度比型別安全重要
- 團隊完全沒有 TS 經驗:如果時程很趕,硬導入 TypeScript 反而拖慢進度
重點是:TypeScript 是一個工具,不是信仰。根據情境選擇就好。
如何開始使用 TypeScript?
方法一:框架內建支援
現代前端框架通常都內建 TypeScript 支援:
# React
npx create-react-app my-app --template typescript
# Vue
npm create vue@latest # 選擇 TypeScript 選項
# Angular(預設就是 TypeScript)
ng new my-app方法二:手動編譯
使用 tsc(TypeScript Compiler)將 .ts 檔案編譯成 .js:
# 安裝 TypeScript
npm install -g typescript
# 編譯單一檔案
tsc hello.ts
# 編譯整個專案
tsc