Tools mentioned in this article
Open the browser-based tool while you read and try the workflow immediately.
在處理 API 回應的 TypeScript 開發中,對應 JSON 的型別定義無法迴避。一邊盯著巢狀很深的 JSON、一邊手寫 interface,既枯燥又是打錯字的溫床。

本文以轉換範例展示 實際的 JSON 會變成什麼樣的 TypeScript 型別,並說明自動生成的訣竅與注意事項。
基礎:扁平物件的轉換
先從簡單的例子開始。
{
"id": 42,
"name": "Alice",
"isActive": true
}
它會變成下面的型別。各值的型別(number / string / boolean)可以從實際值機械式地推導。
interface User {
id: number;
name: string;
isActive: boolean;
}
含巢狀與陣列的轉換
實際的 API 回應會包含物件巢狀與陣列。
{
"id": 42,
"name": "Alice",
"roles": ["admin", "editor"],
"profile": {
"age": 30,
"city": "Tokyo"
}
}
慣例是從元素型別將陣列定為 string[],並把巢狀物件拆成獨立的 interface。
interface Profile {
age: number;
city: string;
}
interface User {
id: number;
name: string;
roles: string[];
profile: Profile;
}
容易踩到的重點
null 與選擇性屬性
當 JSON 含有 null 時,光看那個值無法判斷該欄位是「總是可能為 null」還是「剛好這次為 null」。
{ "nickname": null, "deletedAt": null }
機械式轉換會得到 nickname: null,但實務上大多應是 string | null 或 nickname?: string。生成後依 API 規格手動微調才是務實的做法。
interface User {
nickname: string | null; // 也可能會有值
deletedAt?: string; // 欄位本身可能不存在
}
注意以字串包裝的數字
像 "price": "1980" 這樣把數字以字串包裝的 API 並不少見。生成工具會將其推導為 string。若要在程式中運算,請將型別改為 number 或在接收後轉換,事先決定好方針。
空陣列無法決定型別
像 "tags": [] 這樣的空陣列無法推導元素型別,容易變成 never[] 或 any[]。請使用含有元素的樣本,或在生成後手動指定為 string[] 等。
使用自動生成的步驟
- 從瀏覽器 Network 分頁或 curl 輸出複製實際的回應
- 貼到 JSON → TypeScript 型別生成工具
- 將根 interface 名稱由
Root改成UserResponse之類 - 依規格調整
null與選擇性欄位 - 貼回專案即完成
重點是使用盡量貼近正式、欄位齊全的樣本。樣本貧乏會漏掉選擇性欄位與型別的變動。
當型別不夠時,改用 Zod
TypeScript 的型別是「編譯期」的檢查。外部 API 實際回傳的資料未必符合你的型別。若也想在執行期驗證資料形狀,建議用 JSON → Zod Schema 生成 建立驗證 Schema,並以 schema.parse(data) 加上入口檢查。Zod 也能推導型別,讓你把型別與驗證統一管理。
常見問題
每次都要更改生成型別的根名稱,很麻煩。
多數工具會把根輸出成通用的 Root。最省事的做法是在複製後,用尋找取代換成專案的命名規範(ApiResponse、UserProfile 等)。巢狀 interface 的名稱通常已貼合其內容,因此多數情況只改根即可。
想把 snake_case 的 API 當成 camelCase 使用。
生成的型別會原樣反映 JSON 的鍵,所以會得到 created_at 這類名稱。若要全專案統一為 camelCase,慣例是在 API 邊界處轉換(用對應函式或 camelize 類函式庫)。讓型別定義貼合 API 實體、並明確地進行轉換,就不會混亂。
TypeScript 型別與 Zod Schema,應該先做哪一個?
若需要執行期驗證,建立 Zod Schema 並用 z.infer 推導型別,可統一管理,較為推薦。若內部可信任資料只需編譯期檢查,僅生成 TypeScript 型別即可。對外部 API、表單輸入等「不可信任的輸入」使用 Zod 較安全。