TypeScript 基礎概念 ─ 常見開發工具(VSCode IntelliSense、tsc CLI)
簡介
在前端與 Node.js 生態系統中,TypeScript 已成為主流的靜態型別工具。它不僅讓程式碼更安全,也提升了團隊協作的可讀性與維護性。要真正發揮 TypeScript 的威力,離不開兩個核心工具:
- VSCode IntelliSense – 直接在編輯器裡提供即時型別提示、錯誤偵測與自動完成。
- tsc CLI – TypeScript 官方的編譯器,負責把 .ts 檔案轉譯成可執行的 JavaScript。
本篇文章將從實務角度說明這兩個工具的使用方式、常見陷阱與最佳實踐,讓你在專案中快速上手、提升開發效率。
核心概念
1️⃣ VSCode IntelliSense 基礎
VSCode 內建 TypeScript 語言服務,只要安裝了 VSCode 本身與 TypeScript(npm 安裝或全域安裝),IntelliSense 就會自動啟用。
| 功能 | 說明 |
|---|---|
| 自動完成 | 變數、屬性、方法名稱會在你鍵入時即時顯示建議。 |
| 型別提示 | 滑鼠懸停在變數或函式上會顯示完整的型別資訊。 |
| 快速修復 (Quick Fix) | 出現錯誤時,按 Ctrl+. 可看到自動修正建議,如加入缺少的 import。 |
| 跳轉定義 | F12 或 Ctrl+點擊 可直接跳至型別或實作的宣告位置。 |
範例 1:即時型別提示
interface User {
id: number;
name: string;
email?: string; // 可選屬性
}
// 下面變數在鍵入 user. 時,IntelliSense 會列出 id、name、email
const user: User = { id: 1, name: "Alice" };
user. // ← 此處會出現提示
小技巧:在
jsconfig.json或tsconfig.json中設定"include": ["src"],可以讓 IntelliSense 正確索引專案檔案。
2️⃣ tsc CLI 基本使用
tsc(TypeScript Compiler)是將 TypeScript 轉譯為 JavaScript 的指令列工具。最簡單的使用方式只需要安裝 TypeScript:
npm install -D typescript # 本地開發依賴
# 或全域安裝
npm install -g typescript
2.1 單檔編譯
npx tsc src/index.ts
上述指令會在同目錄產生 index.js,預設使用 ES5 目標與 CommonJS 模組系統。
2.2 使用 tsconfig.json 管理設定
在大型專案中,我們會建立 tsconfig.json 以集中管理編譯選項與檔案範圍。
{
"compilerOptions": {
"target": "ES2022", // 產出 ES2022 語法
"module": "ESNext", // 使用 ES 模組
"strict": true, // 啟用 all strict checks
"noImplicitAny": true, // 禁止隱式 any
"sourceMap": true, // 產生 .map 供除錯使用
"outDir": "dist", // 輸出目錄
"rootDir": "src", // 原始碼根目錄
"esModuleInterop": true, // 允許 default import CJS 模組
"skipLibCheck": true // 加速編譯(跳過 .d.ts 檢查)
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
重點:
"strict": true會一次開啟多項嚴格檢查,對於 新手 來說是最佳的防呆設定。
2.3 監看模式(Watch Mode)
開發時常需要即時編譯,--watch(或 -w)可以讓 tsc 持續監聽檔案變動。
npx tsc -w
每當 src 目錄下的 .ts 檔案變更,編譯器會自動重新產出 dist 內的 JavaScript。
2.4 建立執行腳本(npm script)
{
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"start": "node dist/index.js"
}
}
這樣只要執行 npm run watch 就能即時編譯,npm run build 則是一次性產出。
3️⃣ 常見程式碼範例
以下示範 5 個實用的 TypeScript 範例,每個都結合 IntelliSense 與 tsc 的特性。
範例 2:函式參數的預設值與型別推斷
function greet(name: string = "世界"): string {
// IntelliSense 會提示 name 為 string
return `哈囉,${name}!`;
}
console.log(greet()); // 哈囉,世界!
console.log(greet("小明")); // 哈囉,小明!
說明:預設值讓呼叫者可省略參數,編譯器會自動推斷
name為string。
範例 3:使用泛型(Generics)建立可重用的資料結構
// 宣告一個泛型 Stack
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
// VSCode IntelliSense 會顯示 push/pop 的正確型別
const numberStack = new Stack<number>();
numberStack.push(10);
// numberStack.push("字串"); // ❌ 會在編譯階段報錯
const stringStack = new Stack<string>();
stringStack.push("hello");
範例 4:模組匯入與 esModuleInterop
// 假設有一個第三方套件 lodash
import _ from "lodash";
const arr = [1, 2, 3, 4];
const shuffled = _.shuffle(arr); // IntelliSense 完整顯示 lodash 方法
console.log(shuffled);
提示:若
esModuleInterop為false,上述import _ from "lodash"會產生錯誤,必須改成import * as _ from "lodash"。
範例 5:使用 declare 宣告全域變數(配合 VSCode 提示)
// global.d.ts
declare const API_ENDPOINT: string;
// app.ts
console.log(`API 位於 ${API_ENDPOINT}`);
// IntelliSense 會提示 API_ENDPOINT 為 string
範例 6:設定 paths 別名,讓 import 更簡潔
// tsconfig.json (額外加入)
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@utils/*": ["src/utils/*"]
}
}
}
// src/main.ts
import { formatDate } from "@utils/date";
console.log(formatDate(new Date()));
VSCode 會自動解析 @utils 別名,點擊即可跳到實際檔案。
常見陷阱與最佳實踐
| 陷阱 | 為何會發生 | 解決方案 |
|---|---|---|
未設定 tsconfig.json |
編譯器使用預設設定,可能產出不符合專案需求的 JavaScript(例如 ES5) | 必建 tsconfig.json,明確指定 target、module、strict 等選項 |
使用 any 逃避型別檢查 |
會失去 TypeScript 的安全保障,導致執行時錯誤難以追蹤 | 盡量避免 any,改用 unknown 或自訂型別,並啟用 "noImplicitAny": true |
| 版本不一致的 TypeScript | 開發者本機與 CI 環境使用不同的 TypeScript 版本,可能產生不相容的錯誤 | 在 package.json 中固定 TypeScript 版本,使用 npm ci 於 CI 端安裝 |
| 忽略編譯錯誤直接執行 | tsc 會產出 .js 檔,即使有錯誤也會寫入,執行時會崩潰 |
在 CI 或 npm run build 時加入 --noEmitOnError,確保有錯誤時不產出檔案 |
未開啟 sourceMap |
除錯時只能看到編譯後的 JavaScript,難以定位 TypeScript 原始碼 | 在 compilerOptions 加入 "sourceMap": true,配合 VSCode Debugger 使用 |
最佳實踐清單
- 啟用 Strict Mode:
"strict": true為防呆第一步。 - 使用
paths別名:減少相對路徑的層層上移,提高可讀性。 - 加入 Linter(ESLint + @typescript-eslint):自動檢查風格與潛在錯誤。
- 設定
exclude:避免編譯node_modules、dist等不必要的目錄,加速編譯。 - 在
package.json中加入prepublishOnly:確保發佈前已成功編譯。
{
"scripts": {
"lint": "eslint 'src/**/*.{ts,tsx}'",
"build": "tsc",
"prepublishOnly": "npm run lint && npm run build"
}
}
實際應用場景
| 場景 | 為何需要 VSCode IntelliSense & tsc | 具體做法 |
|---|---|---|
| Node.js 後端服務 | 大量資料模型(DTO)與資料庫 ORM 需要嚴格型別,IntelliSense 可即時提示欄位名稱。 | 使用 ts-node-dev -r tsconfig-paths/register src/server.ts 結合 tsc -w,確保開發時即時編譯與除錯。 |
| React 前端專案 | JSX/TSX 結合型別,IntelliSense 能協助找出錯誤的 Props、State。 | 建立 tsconfig.json 中的 jsx: "react-jsx",並在 VSCode 中安裝 ESLint、Prettier 擴充套件提升開發體驗。 |
| 共用函式庫(npm package) | 需要產出 .d.ts 給使用者,tsc 的 declaration 選項不可或缺。 |
在 tsconfig.json 加入 "declaration": true, "emitDeclarationOnly": true,並在 CI 中驗證產出的型別檔。 |
| 微服務/Monorepo | 多子專案共享相同型別定義,使用 project references 可加速增量編譯。 |
在根目錄建立 tsconfig.base.json,子專案透過 "references": [{ "path": "../shared" }] 互相引用。 |
總結
- VSCode IntelliSense 為開發者提供即時型別提示、錯誤偵測與快速修復,是提升開發效率的第一把利器。
- tsc CLI 負責把 TypeScript 編譯為可執行的 JavaScript,透過
tsconfig.json能夠細緻控制編譯行為與輸出品質。 - 正確設定 Strict Mode、paths 別名、sourceMap,並配合 npm script、watch mode,可以讓開發流程更流暢、錯誤更早被捕捉。
- 避免使用
any、忽略編譯錯誤、版本不一致等常見陷阱,並遵循 Lint + CI 的最佳實踐,才能在大型專案中維持程式碼品質。
掌握了這兩個工具後,你就能在 TypeScript 的世界裡如虎添翼,無論是前端 UI、Node.js 後端,或是跨平台函式庫,都能以安全、可維護的方式快速開發。祝你寫程式愉快,持續在型別安全的道路上前進!