🎯 什麼情境該想到我

當你「明明傳的就是那個字串,TS 卻說 string 不能指派給 "rock" | "country"」的時候。

⚙️ 怎麼用(步驟 / 公式)

先理解為什麼會被推寬——TS 是照「還能不能被改」推的

宣告推論結果原因
let x = "rock"stringlet 可以重新指派,所以推寬以容納未來的值
const x = "rock""rock"const 不能重新指派,可以安全地推成字面量
const o = { s: "rock" }{ s: string }⚠️ 物件屬性即使在 const 下仍可變,所以照樣推寬

第三列是最常踩的坑:你用了 const,但物件裡面的屬性還是被推成 string

三種修法,按情境挑

// 1. 標註變數:可以重新指派,但限制在聯集內
let genre: AlbumGenre = "rock";
 
// 2. 標註物件:整體受約束(但會抹掉精確推論)
const attrs: AlbumAttributes = { status: "on-sale" };
 
// 3. as const:整個結構凍成唯讀的字面量
const attrs = { status: "on-sale" } as const;

as const 拿來做 JS 風格的列舉

這是它最有價值的用法之一——一份來源,同時給你執行期的值與型別

const albumTypes = {
  CD: "cd",
  VINYL: "vinyl",
  DIGITAL: "digital",
} as const;
 
type AlbumType = (typeof albumTypes)[keyof typeof albumTypes];
// "cd" | "vinyl" | "digital"

比起手寫一份 type AlbumType = "cd" | "vinyl" | "digital",這樣不會有兩份會走鐘的來源

🧪 我實際套用的紀錄

  • 2026-08-28:(待填)

⚠️ 注意 / 什麼時候不適用

  • as const 會讓整個結構唯讀。之後要改它就會報錯——那通常是好事,但如果那個物件本來就要被修改,就不該用。
  • 不要對真的需要重新指派的變數硬套 const。要可變就用 let 加標註,那才是對的工具。
  • as const 不是 as。它是推論指示,不是型別斷言,不會繞過檢查。
  • 書裡的觀察值得記:TS 這個設計會自然推著你多用 const,因為它比較嚴格。

🔗 相關工具