JSON 轉 TypeScript 型別定義生成器
貼上 JSON 物件(或 JSON 陣列),即可自動生成對應的 TypeScript interface/type 定義。
由 JSON 產生 TypeScript 型別定義
在 TypeScript 中接收 API 回應時,首先需要的就是型別定義。然而一邊盯著層層巢狀的 JSON 一邊手寫 interface 既費神,也正是最容易漏寫屬性或弄錯型別的工作。本工具只要貼上 JSON,即可自動產生對應的 interface 與 type。
產生時會依值在 JavaScript 上的型別來推斷 TypeScript 的型別。巢狀的物件會被抽出為另一個 interface,陣列則由元素的型別導出 T[]。根型別的名稱可自由指定,因此產物可直接貼進專案。由於推斷完全基於您所貼上的樣本,可能被省略的屬性與可能為 null 的欄位,請在產生後自行補上 ? 或聯合型別。 所有處理都在瀏覽器中完成。
產生型別定義的步驟
- 貼上 JSON 把 API 的回應範例原樣輸入即可。物件或陣列皆可。
- 決定根型別的名稱 它會成為所產生最上層 interface 的名稱,保留預設值也無妨。
- 查看產生結果 巢狀的物件會被抽出為獨立的 interface 並列出。
-
自行補上可省略的欄位
樣本中未出現的欄位無法推斷。 請自行加上
?與| null。 -
複製後貼進專案
可直接貼入
.ts檔案。
用好本工具的小技巧
- 當陣列中的所有元素都是物件時,會合並各元素的鍵生成一個 interface。部分元素缺失的鍵會自動標記為可選屬性(
?)。 - 根型別名稱預設是 "Root",可以修改為你喜歡的名稱(例如
User、ApiResponse)。巢狀物件的 interface 名稱會根據其所在的屬性名自動生成。 - 直接貼上 API 響應的示例 JSON,即可快速獲得前端開發中所需型別定義的初稿。
- 生成的結果只是根據結構推斷出的型別初稿。建議對照實際的 API 規範(是否可為 null、必填欄位等)手動調整。
這些情境會用到
為外部 API 準備型別
即便 API 文件未提供型別定義,只要有回應範例便能做出起點。
為既有的 JSON 設定檔加上型別
想以型別安全的方式讀取設定檔時,可把結構直接落成型別。
由模擬資料反推型別
先行開發前端時,可由暫用資料準備型別。
檢驗手寫型別的疏漏
把手寫的型別定義與產生的型別對照,即可找出遺漏之處。
TypeScript 的術語
- interface
- 描述物件形狀的宣告。同名多次宣告會自動合併,這正是它與 type 的差別。
- type 別名
- 為任意型別命名的宣告。聯合型別與基本型別也能被命名。
- 可省略屬性
- 如
name?: string這般帶?的欄位。陣列中只有部分元素才有的鍵會自動加上它,但僅憑單一物件無法推斷某個欄位是否可省略。 - 聯合型別
- 如
string | null,表示可為多種型別之一。 - 巢狀物件
- 值本身又是物件的結構。本工具會將其抽出為獨立的 interface。
- 型別推斷
- 由值導出型別。此處的推斷基於您所貼的單一樣本,未必等同 API 的實際規格。
常見問題
?)。如果同一個鍵在不同元素中型別不同,則會表示為聯合型別(例如 string | number)。profile 的物件會生成名為 Profile 的 interface)。如果需要同名但結構不同的 interface,會在末尾新增序號加以區分。
閒話 ― 型別推斷工具解決的"型別偏差"問題
TypeScript 是一門可以在編譯期藉助靜態型別發現 bug 的語言,但對於從外部 API 獲取的 JSON 資料,如果開發者不手動定義型別,TypeScript 編譯器是無從得知其結構的。每當 API 規範與實際響應出現偏差,或者欄位被增刪,都需要手動更新型別定義,這種"型別定義與 API 實際情況不一致"的問題一直困擾著許多前端專案。
JSON 轉 TypeScript 工具通過從實際返回的示例 JSON 反向推算型別,大幅提升了這項工作的效率。同類工具中比較有名的是 quicktype(一個可以生成多種語言型別定義的開源工具),它以支援 JSON Schema、GraphQL schema 等多種輸入格式而聞名。
型別推斷的難點在於,JSON 本身並不包含"這個欄位是否總是存在""未來是否可能變為 null"等資訊。因此自動生成的型別定義並非萬能,實踐中的通行做法是將其視為僅反映"本次示例資料結構"的初稿,再對照實際的 API 規範進行調整。