1. 什麼是型別元程式設計?
TypeScript 的型別系統本身是 **Turing-complete (圖靈完備)** 的。這意味著我們可以在「編譯期 (Compile Time)」執行強大的型別層級運算,將常見的 Runtime 錯誤攔截在開發階段。
2. Conditional Types 與 infer 實戰
透過 infer 關鍵字,我們可以輕鬆拆解非同步 Promise 或解構 API 的回應型別:
// 自動解構 Promise 或回傳非 Promise 原始型別
type UnwrapPromise = T extends Promise ? UnwrapPromise : T;
type AsyncData = Promise>;
type RealData = UnwrapPromise; // { id: string; name: string }
3. Template Literal Types 模板字面量型別
結合字串範本,可以在型別層級自動檢查 API 路由格式:
type EventName = 'click' | 'hover';
type Component = 'button' | 'card';
// 自動推導為 'button:click' | 'button:hover' | 'card:click' | 'card:hover'
type ActionEvent = `${Component}:${EventName}`;
4. 型別安全 API Client 建構實戰
以下示範如何在前端與後端共用型別契約時,打造擁有 IntelliSense 自動補全的 API Client:
interface APIContract {
'GET /api/v1/users': { response: { id: number; name: string }[] };
'POST /api/v1/users': { body: { name: string }; response: { id: number } };
}
async function fetchAPI(
endpoint: K,
options?: APIContract[K] extends { body: infer B } ? { body: B } : undefined
): Promise {
const [method, path] = endpoint.split(' ');
const res = await fetch(path, {
method,
headers: { 'Content-Type': 'application/json' },
body: options?.body ? JSON.stringify(options.body) : undefined
});
return res.json();
}
// 擁有全型別自動補全!
const users = await fetchAPI('GET /api/v1/users');
5. 常見問題解答 (FAQ)
Q: TypeScript 中的 infer 關鍵字在何時使用?
infer 用於條件型別 (Conditional Types) 之中,能在編譯期動態解構並提取函式回傳值、Promise 包裝內容或陣列元素的真實型別。