TypeScript 入門:為什麼推薦用 TypeScript 而不是 JavaScript?
2025年7月25日
在開發應用程式時,相信大家都對程式編輯器中,時不時會出現的紅色波浪底線不陌生。這些紅波浪底線會在我們拼錯字、寫出不符 linter 規範時跳出來提醒我們,確保我們不會犯下基本的低級錯誤。
有在寫 JavaScript 的讀者,可能用過 Prettier 或 ESLint (或是近期更流行的 Biome 或 OXC),來幫忙抓問題。然而,雖然這些工具能幫忙抓程式碼風格與規範的問題,它們無法抓型別相關的問題。舉例來說,假如某個變數是 undefined
,但某段程式碼試圖去拿這個變數的屬性,這種錯誤無法被上述提到的工具提醒;因此可能導致程式碼部署,實際在瀏覽器跑的時候出錯,讓錯誤直接影響到使用者。
顯然這不太理想,因此如果能有機制解決這類問題,能夠像 Prettier 或 ESLint 一樣,在寫程式時就報錯,不用等程式碼都被部署後才發現有錯,這樣會對開發者很有幫助。
TypeScript 正是能幫忙做到這件事的好工具。比起 JavaScript,用 TypeScript 能讓我們能在寫程式時,及早發現問題,避免某些能先發現的 bug 被部署到線上影響到使用者。
在這個系列文,我們會有淺到深談 TypeScript。在系列文的第一篇,讓我們先來談 TypeScript 是什麼,以及在實際開發中,為什麼推薦用 TypeScript 而不是純 JavaScript。
TypeScript 是什麼?
如其名所述,TypeScript 是有型別的 JavaScript。如果要更精確地說,TypeScript 是 JavaScript 的超集合 (superset)。意思是每個有效的 JavaScript 程式碼,同時也是有效的 TypeScript 程式碼。你可以拿任何 .js
檔案,重新命名為 .ts
,程式都會能正常運作。換句話說,TypeScript 並不是在取代 JavaScript,而是在 JavaScript 的基礎上進行擴充。
這樣聽起來可能還是很抽象,讓我們透過具體的例子來了解 TypeScript 與 JavaScript 的區別。
先來看一個一般的 JavaScript 函式:
function greet(name) {
return "Hello, " + name + "!";
}
greet("World"); // "Hello, World!"
greet(42); // "Hello, 42!" (這可能不是我們要的結果)
同樣的函式用 TypeScript 寫會是這樣,可以看到我們為 name
加了 string
這個型別,同時也為 greet
的輸出加了型別:
function greet(name: string): string {
return "Hello, " + name + "!";
}
greet("World"); // "Hello, World!"
greet(42); // 會報出 Argument of type 'number' is not assignable to parameter of type 'string' 這個錯誤
在上面的例子中,可以發現當我們加了 : string
來告訴 TypeScript 我們預期接收什麼型別的資料,TypeScript 就可以在程式執行之前就先幫忙抓到錯誤,所以 greet(42)
會在我們實際執行程式前就報錯。這是很重要的關鍵區別,因為這等同於在程式碼被用之前,先有一層型別的安全網,避免有型別問題的程式碼在線上被使用者用到。
TypeScript 如何解決 JavaScript 開發者的痛點?
在上一段的最後,我們談了 TypeScript 是在 JavaScript 上面加上型別,同時也提到這層型別有如安全網一般。不過具體來說,TypeScript 在實務開發上,解決了哪些 JavaScript 開發者的痛點? 讓現在絕多數的團隊,都選用 TypeScript 而不是純 JavaScript。
也許大家可以先試著回想一下,過去在寫 JavaScript 時遇過哪些問題。相信多數人可能都遇過,某段程式在寫的時候不覺得有問題,結果在瀏覽器上面跑的時候,卻整個程式崩掉,查看錯誤後發現是 undefined is not a function
這種錯誤。
在上面的這個例子中,最讓開發者心驚膽戰的,不是錯誤本身,而是錯誤是等到程式實際在瀏覽器或伺服器上執行,使用者已經在用的時候才發現。當程式已經在瀏覽器或伺服器運行時,我們會說這是執行時期(runtime)。
純 JavaScript 基本上只會在執行時期報出錯誤,但往往這時候才報錯,已經為時已晚,因為使用者已經受到波及。相比之下,TypeScript 則是在**編譯時期 (compile time)**就能指出錯誤,也就是在還在寫程式碼時,邊寫就會邊被 TypeScript 提醒有潛在的錯誤,這能讓開發者及早修改,避免有問題的程式碼被部署上線。
在開發 JavaScript 應用程式時,相信大家對下面這種情況都不陌生:
const user = getUser();
console.log(user.name.toUpperCase()); // 平常跑得好好的,直到 getUser() 回傳 null
這段程式碼看起來沒什麼問題,平時也能正常運作。但某天如果 getUser()
回傳了 null
,整個應用程式就會因為「Cannot read property 'toUpperCase' of null」而直接崩掉。
這時候,TypeScript 就能派上用場。它會在程式執行前就幫你抓到這種潛在問題:
const user = getUser(); // TypeScript 知道這可能回傳 null
console.log(user.name.toUpperCase()); // 錯誤:Object is possibly 'null'
當你寫上面這段 TypeScript 程式碼,編輯器馬上會跳出紅色波浪線,提醒你 user
有可能是 null
,必須先處理這種情況才能繼續呼叫 toUpperCase。因此需要調整成下面這樣,才能通過 TypeScript 的檢查:
const user = getUser();
if (user) {
console.log(user.name.toUpperCase()); // 現在這樣才是安全的
}
從上面的例子可以看到,TypeScript 能把原本要等到執行時才會報的錯誤,提前在開發階段就攔下來,這正是為什麼現在多數團隊會選用 TypeScript 而不是 JavaScript。
TypeScript 帶來的四大好處
看完上面的例子後,讓我們來彙整 TypeScript 還有哪些其他的好處,以下四點是推薦用 TypeScript 的原因。
1. 減少上線後的 bug
很多人一開始可能會覺得 TypeScript「很囉唆」,紅色底線常常跳出來干擾。但實際上,這些提示幾乎都是在保護開發者。每次 TypeScript 跳出型別錯誤的警告,背後就是在幫開發者避免某個可能在線上出錯的問題,讓開發者減少要半夜被叫起來 debug 的慘劇。這就像在寫程式時多了一層安全網,幫忙把問題擋在上線之前。
2. 讓程式碼自帶說明書
在 JavaScript 中,我們常常要靠變數名稱猜這個 function 接什麼、回傳什麼。但 TypeScript 把型別直接寫在函式定義裡,會跟程式碼同步,不會像過時的文件一樣誤導人。
function calculateTax(price: number, rate: number): number {
return price * rate;
}
看到上面這段程式碼,開發者馬上就知道這個函式需要什麼參數、會回傳什麼結果。不用猜變數名稱,也不用翻遍程式碼去找實作細節,這種清晰度讓維護起來輕鬆不少。
3. 更好的開發體驗
當你在編輯器裡打 user.
時,如果是 JavaScript,IDE 通常只能猜測有哪些屬性,可能還會猜錯。但如果改成用 TypeScript,因為已經定義過 user
的型別,IDE 會非常精準地幫忙列出可以用的屬性,還會幫你過濾掉拼錯字的可能性。
這種型別資訊還能讓重構變得輕鬆又安心。純 JavaScript 的重構就像在黑暗中摸索,可能用搜尋替換改了函式參數或屬性名稱,但無法確切知道有沒有漏掉什麼地方。TypeScript 則像裝了導航系統,它會追蹤整個專案的程式碼使用狀況,當改動時,馬上告訴開發者哪些地方需要調整,不用上線後還要祈禱沒出錯。
4. 打造更乾淨的程式架構
用 TypeScript 時,會發現自己開始更認真思考程式碼結構。因為需要先定義介面和型別,這就像在為應用程式畫一張藍圖,梳理清楚不同模組之間的關係。一開始可能會覺得這多花了點時間,但長期來看,這會讓程式碼更有條理,資料流也更清晰。開發者比較不容易寫出亂七八糟的相依關係,或是搞不清楚資料從哪來、要幹嘛。
學習 TypeScript 的挑戰
如果你讀到這裡,可能會覺得 TypeScript 聽起來很棒。雖然 TypeScript 很強大,但實話是 TypeScript 不是那種能讓 JavaScript 開發者無痛上手的語言。它有相對陡峭的學習曲線,特別是最開始的時候,你可能會被一堆型別錯誤搞得有點崩潰,甚至會想:「這在 JavaScript 明明跑得好好的,為什麼 TypeScript 一直跳錯?」
但撐過幾週後,會慢慢開始感受到 TypeScript 的價值:
- 你會在問題發生前就抓到 bug,省下不少麻煩
- 重構變得很安心,不用怕改一個東西壞三個地方
- 型別錯誤不再是阻礙,而是提醒你重新思考資料結構
- 紅底線從惱人變成可靠的朋友
TypeScript 真正的價值,就像一位嚴格的老師,這位老師會透過嚴格的規範,迫使開發者寫出更好的程式碼。那些型別錯誤不是在找大家麻煩,而是在幫忙發現潛在的問題。
加入 E+ 成長計畫
如果你覺得這篇內容有幫助,喜歡我們的內容,歡迎加入 ExplainThis 的 E+ 成長計畫,透過每週的深度主題文,以及技術討論社群,讓讀者在前端、後端、軟體工程的領域上持續成長。