Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

TypeScript Type Inference:讓編譯器自動幫你標註型別

最後更新:2026年5月19日JavaScript

寫 TypeScript 的時候,你可能會覺得每個變數都要手動標註型別很麻煩。

但其實大部分情況下,你根本不需要自己寫——TypeScript 會自動幫你推論出來。

這個機制叫做 Type Inference(型別推論),而且它比你想像中更常用。

什麼是 Type Inference?TypeScript 幫你自動判斷型別

先來看這兩個英文字。

Type 就是「型別」,像是 string、number 這些你已經知道的東西。

Inference 這個字比較少見,它的意思是「推論」——就是根據現有的線索,去判斷出一個結論。

所以 Type Inference 合在一起,就是「型別推論」,意思是 TypeScript 根據你寫的程式碼,自動推論出變數的型別。

你不需要明確寫出型別,TypeScript 會根據你給的值,自己判斷出這個變數是什麼型別。

舉個生活中的例子:假設你跟朋友在聊天,對方講了一句話,雖然沒有明說,但你覺得他在暗示你很笨。

這時你可能會說:「你是不是在暗示我是笨蛋?」

對方沒有直接講出來,但你從他的話裡面「推論」出了這個意思——這就是 Inference。

TypeScript 做的事情也一樣——它不需要你明確告訴它型別是什麼,它會自己從程式碼中推論出來。

型別推論 vs 手動標註:差在誰來決定型別

先看手動標註型別的寫法:

let greeting: string = "hello pikachu";

這裡的 : string 就是你明確告訴 TypeScript:「這個變數是字串。」

這種寫法很直覺,型別寫得清清楚楚。

但其實你根本不用寫 : string,因為 TypeScript 早就知道它是 string 了。

把型別拿掉,改成這樣:

let greeting = "hello pikachu";

你沒有寫 : string,但如果你把滑鼠移到 greeting 上面,TypeScript 還是會告訴你它是 string。

這就是 Type Inference 在運作。

TypeScript 在背後看到你賦值了一個字串,就自動幫你把型別標註為 string。

這個過程是隱形的,你不會在程式碼裡看到它,但它確實存在。

所以這兩種寫法的效果是一樣的。

差別只在於:手動標註是你自己告訴 TypeScript 型別是什麼,而型別推論是讓 TypeScript 自己去判斷。

寫專案時,可以放心靠型別推論嗎?

很多初學者會擔心:型別推論是 TypeScript 自動判斷的,那它可靠嗎?實際工作上可以這樣偷懶不寫型別嗎?

答案是:可以,而且這是很常見的做法。

在實際的工作環境中,變數的型別推論是被廣泛接受的,你不需要每個變數都手動標註型別,讓 TypeScript 自己推論就好。

關鍵原因前面已經提過:推論出來的型別跟手動標註是一樣的,型別檢查照樣會生效,你並沒有因此失去任何保護。

換句話說,下面這兩種寫法在 TypeScript 眼中沒有差別:

let count: number = 0;   // 手動標註
let count = 0;           // 交給推論

兩種寫法,count 都是 number,之後如果你不小心把字串塞進去,TypeScript 一樣會跳出錯誤。

既然效果一樣,那何必每個變數都多打一次型別呢?這就是為什麼實務上大家傾向讓推論去處理。

而且過度標註型別,反而會讓程式碼變得囉嗦、不好讀。

當變數的初始值已經很明顯(像 0、"hello"、true),再寫一次 : number、: string、: boolean 就只是重複資訊。

函式參數是少數例外

不過有一個地方要特別注意:函式(function) 的參數通常還是建議手動標註型別。

原因在於,一般變數宣告的當下就有初始值,TypeScript 看著那個值就能推論出型別。

但函式的參數不一樣——你在「定義」函式的時候,參數還沒有任何值,那個值要等到「呼叫」函式時才會傳進來。

沒有值可以參考,TypeScript 自然就很難自動判斷參數該是什麼型別。

所以函式參數通常需要你自己標註,例如:

function greet(name: string) {
  return "hello " + name;
}

這裡的 name: string 就得自己寫,不然 TypeScript 不知道 name 是什麼型別。

一句話原則:變數靠推論,參數要標註

總結成一句話:一般變數放心交給型別推論,函式參數則自己手動標註。

這也是多數實際專案採用的寫法——不是每個地方都標、也不是每個地方都不標,而是「該推論的推論、該標註的標註」。

千萬不要用 any 來跳過型別

學到這裡,你已經知道「不用手動寫型別,TypeScript 會自己推論」。

這時候如果有人跟你說還有一個叫 any 的東西,用了它就「不用管型別」,你很可能會覺得:這聽起來跟型別推論差不多嘛,都是「我不用自己寫型別」。

先說清楚:會這樣想很正常。因為這兩件事表面上真的很像。

型別推論,是你不寫型別、讓 TypeScript 去判斷。

any,也是你不寫出一個明確的型別。

兩者從「開發者有沒有動手寫型別」這個角度看,都是「我沒有特別去指定型別」——所以初學者很容易把它們當成同一類的「省事寫法」。

但這就是陷阱所在:它們表面像,骨子裡卻是相反的兩件事。

關鍵差別在於「型別還在不在」。

型別推論的情況,型別其實一直都在,只是 TypeScript 幫你補上、你看不到而已,型別檢查照常運作。

而 any 的情況,是型別檢查被直接「關掉」了。

來看 any 怎麼寫:

let greeting: any = "hello pikachu";

你明確寫了 : any,這等於告訴 TypeScript:「這個變數什麼型別都可以,不用幫我檢查。」

這樣一來,TypeScript 就完全不會幫你檢查這個變數了。

之後就算你把它當數字、當陣列亂用,TypeScript 也不會吭一聲——你也就失去了 TypeScript 最大的優勢,也就是型別安全。

有些人會用 any 來快速閃過型別錯誤,但這只是把問題藏起來,不是解決問題,是一個很不好的習慣。

所以記住這個對比就好:

  • 型別推論:你沒寫型別,但型別還在,檢查照常運作 → 放心用。
  • any:你寫了型別,但等於把型別檢查關掉 → 盡量避免。

同樣是「看起來沒在認真寫型別」,一個是 TypeScript 在幫你,一個是你把 TypeScript 的保護親手關掉。

結語:型別推論是你的好幫手

很多初學者一開始會以為,寫 TypeScript 就是要在每個變數後面乖乖加上型別。

但讀完這篇你會發現,事情沒那麼累——大部分時候,TypeScript 會自己把型別推論出來。

最後用幾個重點幫你複習:

  • Type Inference 是 TypeScript 自動推論變數型別的機制,不需要你手動標註。
  • 推論出來的型別跟手動標註的效果一樣,型別檢查一樣會生效,你不會少掉任何保護。
  • 在實務上,變數的型別推論是完全可以接受的做法,不用每個變數都手動標註。
  • 函式的參數則建議手動標註型別,因為定義時還沒有值可以參考,TypeScript 比較難自動推論。
  • 絕對不要用 any,它會關掉型別檢查,等於把 TypeScript 的保護親手關掉。

回到最重要的一句話:型別推論不是壞事,它其實是你的好幫手。

學會放心交給它,你的程式碼會更簡潔,也不會因此失去型別安全。

下一步,你可以再去了解 any 到底是什麼、什麼情況下真的不得不用它——那會是另一個值得認識的主題。

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

JavaScript

目錄

  • 什麼是 Type Inference?TypeScript 幫你自動判斷型別
  • 型別推論 vs 手動標註:差在誰來決定型別
  • 寫專案時,可以放心靠型別推論嗎?
  • 函式參數是少數例外
  • 一句話原則:變數靠推論,參數要標註
  • 千萬不要用 any 來跳過型別
  • 結語:型別推論是你的好幫手