JSON 生態系統示意圖

在現代開發中,JSON 已超越單純的資料格式,成為串連前端與後端的「契約」。能從一個 JSON 樣本派生出型別定義、執行期驗證、API 規格書,正是 JSON 生態系統的強項。

本文以一個 API 回應為例,用實際程式碼串起 格式化 → 生成型別 → 驗證 → 定義 API 的流程。

起點:一個 JSON 回應

我們以下面這個使用者資訊回應為例。

{
  "id": 42,
  "name": "Alice",
  "email": "[email protected]",
  "roles": ["admin"],
  "createdAt": "2026-06-19T10:00:00Z"
}

這一個樣本,就是後續一切的起點。

步驟 1:格式化以掌握結構

實際拿到的 JSON 常是沒有換行的單行,無法直接讀懂結構。請先用 JSON 格式化工具 格式化,確認巢狀深度、是否為陣列、各值的型別。格式化後,「roles 是陣列還是單一值」這類結構才會清晰浮現。

步驟 2:生成 TypeScript 型別

掌握結構後,建立對應的 TypeScript 型別。

interface User {
  id: number;
  name: string;
  email: string;
  roles: string[];
  createdAt: string;
}

使用 JSON → TypeScript 型別生成,只要貼上就能取得此型別。如此一來,編譯期的型別檢查便開始生效。

步驟 3:用 Zod 確保執行期安全

TypeScript 的型別只是編譯期的檢查。外部 API 未必真的回傳符合型別的資料,規格變更或錯誤都可能讓形狀崩壞。因此,為了執行期驗證,準備一份 Zod Schema

import { z } from "zod";

const UserSchema = z.object({
  id: z.number(),
  name: z.string(),
  email: z.string().email(),
  roles: z.array(z.string()),
  createdAt: z.string().datetime(),
});

// 型別可以從 Schema 推導
type User = z.infer<typeof UserSchema>;

// 在入口處驗證
const user = UserSchema.parse(await res.json());

使用 z.infer,即可從 Schema 自動推導 TypeScript 型別,達成 型別與驗證的統一管理。不正確的資料會在 parse 當下以例外被擋下。

步驟 4:用 OpenAPI 打造團隊共通語言

最後,從同一份 JSON 產生 API 規格書(OpenAPI / Swagger)的 Schema,便能成為前端、後端、QA 與外部串接方共享的「共通語言」。

components:
  schemas:
    User:
      type: object
      properties:
        id:       { type: integer }
        name:     { type: string }
        email:    { type: string, format: email }
        roles:    { type: array, items: { type: string } }
        createdAt: { type: string, format: date-time }

JSON → OpenAPI 定義生成 可快速產出此 Schema 的草稿,減少撰寫文件的工夫,把時間用在設計討論上。

全貌:一個 JSON 開枝散葉

   實際的 JSON 回應

   ┌──────┼───────────┬──────────────┐
 格式化   TS 型別    Zod Schema     OpenAPI
 (掌握)  (靜態檢查)  (執行期檢查)   (規格共享)

重點是:這些並非各自獨立的工作,而是從一個樣本派生出來的一連串流程。以實際資料為起點,能防止文件與實作、型別與驗證之間的落差。

常見問題

有了 TypeScript 型別,還需要 Zod 嗎?

型別只在編譯期作用,不會驗證執行期實際收到的資料。對於「不可信任的輸入」——外部 API、表單輸入、LocalStorage——搭配 Zod 等執行期驗證較安全。若是內部就能完結的可信任資料,僅型別也可能足夠。

該用 YAML 還是 JSON 管理資料?

機器之間處理的 API 通訊適合 JSON,人類編輯的設定檔(CI/CD、Kubernetes 等)適合可寫註解的 YAML。兩者可用 JSON ⇔ YAML 轉換 互轉,依用途分開使用即可。

只用一個樣本生成型別可以嗎?

選擇性欄位與可能為 null 的項目,光靠一個樣本會漏掉。請使用欄位盡量齊全的代表性回應,並在生成後依規格手動補上 ?| null