JSON 轉 TypeScript 型別定義生成器

貼上 JSON 物件(或 JSON 陣列),即可自動生成對應的 TypeScript interface/type 定義。

由 JSON 產生 TypeScript 型別定義

在 TypeScript 中接收 API 回應時,首先需要的就是型別定義。然而一邊盯著層層巢狀的 JSON 一邊手寫 interface 既費神,也正是最容易漏寫屬性或弄錯型別的工作。本工具只要貼上 JSON,即可自動產生對應的 interface 與 type。

產生時會依值在 JavaScript 上的型別來推斷 TypeScript 的型別。巢狀的物件會被抽出為另一個 interface,陣列則由元素的型別導出 T[]。根型別的名稱可自由指定,因此產物可直接貼進專案。由於推斷完全基於您所貼上的樣本,可能被省略的屬性與可能為 null 的欄位,請在產生後自行補上 ? 或聯合型別。 所有處理都在瀏覽器中完成。

產生型別定義的步驟

  1. 貼上 JSON 把 API 的回應範例原樣輸入即可。物件或陣列皆可。
  2. 決定根型別的名稱 它會成為所產生最上層 interface 的名稱,保留預設值也無妨。
  3. 查看產生結果 巢狀的物件會被抽出為獨立的 interface 並列出。
  4. 自行補上可省略的欄位 樣本中未出現的欄位無法推斷。 請自行加上 ? 與 | null。
  5. 複製後貼進專案 可直接貼入 .ts 檔案。

用好本工具的小技巧

  • 當陣列中的所有元素都是物件時,會合並各元素的鍵生成一個 interface。部分元素缺失的鍵會自動標記為可選屬性(?)。
  • 根型別名稱預設是 "Root",可以修改為你喜歡的名稱(例如 User、ApiResponse)。巢狀物件的 interface 名稱會根據其所在的屬性名自動生成。
  • 直接貼上 API 響應的示例 JSON,即可快速獲得前端開發中所需型別定義的初稿。
  • 生成的結果只是根據結構推斷出的型別初稿。建議對照實際的 API 規範(是否可為 null、必填欄位等)手動調整。

這些情境會用到

為外部 API 準備型別

即便 API 文件未提供型別定義,只要有回應範例便能做出起點。

為既有的 JSON 設定檔加上型別

想以型別安全的方式讀取設定檔時,可把結構直接落成型別。

由模擬資料反推型別

先行開發前端時,可由暫用資料準備型別。

檢驗手寫型別的疏漏

把手寫的型別定義與產生的型別對照,即可找出遺漏之處。

TypeScript 的術語

interface
描述物件形狀的宣告。同名多次宣告會自動合併,這正是它與 type 的差別。
type 別名
為任意型別命名的宣告。聯合型別與基本型別也能被命名。
可省略屬性
如 name?: string 這般帶 ? 的欄位。陣列中只有部分元素才有的鍵會自動加上它,但僅憑單一物件無法推斷某個欄位是否可省略。
聯合型別
如 string | null,表示可為多種型別之一。
巢狀物件
值本身又是物件的結構。本工具會將其抽出為獨立的 interface。
型別推斷
由值導出型別。此處的推斷基於您所貼的單一樣本,未必等同 API 的實際規格。

常見問題

手動根據 API 響應示例編寫型別定義既耗時又容易出錯,比如寫錯鍵名或漏掉某個型別。自動生成可以大幅節省前端開發者的時間,並減少這類失誤。

工具會合並陣列中所有元素的鍵,只在部分元素中出現的鍵會自動標記為可選屬性(?)。如果同一個鍵在不同元素中型別不同,則會表示為聯合型別(例如 string | number)。

生成的型別定義只是根據示例 JSON 的結構機械推斷出來的。是否可為 null、未來是否會新增欄位等資訊無法僅憑示例 JSON 判斷,建議對照 API 文件手動調整後再使用。

巢狀物件的 interface 名稱會根據存放該物件的屬性名自動生成(例如鍵名為 profile 的物件會生成名為 Profile 的 interface)。如果需要同名但結構不同的 interface,會在末尾新增序號加以區分。
工具君

閒話 ― 型別推斷工具解決的"型別偏差"問題

TypeScript 是一門可以在編譯期藉助靜態型別發現 bug 的語言,但對於從外部 API 獲取的 JSON 資料,如果開發者不手動定義型別,TypeScript 編譯器是無從得知其結構的。每當 API 規範與實際響應出現偏差,或者欄位被增刪,都需要手動更新型別定義,這種"型別定義與 API 實際情況不一致"的問題一直困擾著許多前端專案。

JSON 轉 TypeScript 工具通過從實際返回的示例 JSON 反向推算型別,大幅提升了這項工作的效率。同類工具中比較有名的是 quicktype(一個可以生成多種語言型別定義的開源工具),它以支援 JSON Schema、GraphQL schema 等多種輸入格式而聞名。

型別推斷的難點在於,JSON 本身並不包含"這個欄位是否總是存在""未來是否可能變為 null"等資訊。因此自動生成的型別定義並非萬能,實踐中的通行做法是將其視為僅反映"本次示例資料結構"的初稿,再對照實際的 API 規範進行調整。