TypeScript 型別系統實戰:從基礎到進階工具型別

前端工程(更新於 2026年5月24日)

為什麼工具站需要 TypeScript?

工具庫有 200+ 工具頁、4 語言 i18n、複雜的工具用戶端設定。純 JavaScript 在以下場景容易出錯:

  • 工具設定物件的欄位拼寫錯誤
  • i18n key 不存在但未報錯
  • API 回應結構與預期不符
  • 重構時遺漏更新引用

TypeScript 在編譯期捕獲這些錯誤,而非執行時。


核心型別技巧

1. 型別推斷 vs 顯式標註

// ✅ 讓 TS 推斷(簡潔)
const tools = [{ href: '/pdf/merge', name: 'PDF合并' }] as const;

// ✅ 需要約束時顯式標註
function getTool(href: string): ToolItem | undefined {
  return ALL_TOOLS.find(t => t.href === href);
}

2. 泛型約束

function encode<T extends string | ArrayBuffer>(
  input: T
): T extends string ? string : ArrayBuffer {
  // 根據輸入型別回傳不同結果
}

3. 聯合型別與型別守衛

type ProcessResult =
  | { status: 'success'; data: Blob }
  | { status: 'error'; message: string };

function handleResult(result: ProcessResult) {
  if (result.status === 'success') {
    downloadBlob(result.data); // TS 知道 data 存在
  }
}

進階工具型別

Partial、Required、Pick、Omit

type ToolConfig = {
  href: string;
  name: string;
  blurb: string;
  i18nKey?: string;
};

type ToolUpdate = Partial<ToolConfig>;        // 所有欄位可選
type ToolRequired = Required<ToolConfig>;      // 所有欄位必填
type ToolPreview = Pick<ToolConfig, 'name' | 'blurb'>; // 只取部分

條件型別

type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>;  // true
type B = IsString<42>;       // false

映射型別

type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Nullable<T> = { [K in keyof T]: T[K] | null };

JSON → TypeScript 產生

工具庫 JSON 轉 TypeScript 工具的實作邏輯:

function jsonToTypeScript(json: unknown, name = 'Root'): string {
  if (Array.isArray(json)) {
    return `${name}[]`;
  }
  if (typeof json === 'object' && json !== null) {
    const fields = Object.entries(json).map(([key, value]) => {
      const type = jsonToTypeScript(value, capitalize(key));
      return `  ${key}: ${type};`;
    });
    return `interface ${name} {\n${fields.join('\n')}\n}`;
  }
  return typeof json; // string | number | boolean
}

輸入 API 回應 JSON,一鍵產生 TypeScript interface——減少手動撰寫型別的工作量。


實用模式

satisfies 運算子(TS 4.9+)

const config = {
  locales: ['zh-CN', 'en'],
  defaultLocale: 'zh-CN',
} satisfies RoutingConfig; // 保留字面量型別,同時校驗結構

const 型別參數(TS 5.0+)

function createTool<const T extends string>(href: T) {
  return { href } as const;
}
const tool = createTool('/pdf/merge'); // href 型別為 '/pdf/merge',非 string

總結

TypeScript 的型別系統不僅是「加型別註解」,更是一套編譯期程式設計語言。掌握泛型、條件型別和工具型別,可以建構自文件化、重構安全的程式碼庫。工具庫的 JSON 轉 TypeScript 工具則是型別驅動開發的實用起點。

本站提供瀏覽器本地工具,免註冊即可試用 →

#TypeScript#类型系统#泛型#工具类型#工程化