← Programming Core

TYPESCRIPT CORE · 91

Why Types:TypeScript 到底替你做了什麼?

這條線不把 TypeScript 教成「JavaScript 多寫冒號」。真正核心是:在 code 真正進 Browser / Node 前,用型別資訊先驗證一批不合理操作;但外部 runtime data 仍可能撒謊。

Why now:JavaScript 已經能跑,為什麼還需要 TypeScript?

function total(price, quantity) {
  return price * quantity;
}

total("100", 2);

JavaScript 可以執行這段,而且結果可能剛好是 200。但這種「靠 coercion 剛好能跑」會讓大型專案的 contract 很模糊。

.ts source→ type checker →diagnostics→ emit/build →.js→ Browser / Node →runtime

Learning outcomes

1. Annotation 與 inference

let score: number = 90;

const age = 20;
// TypeScript 通常可推斷 age 是 number

不是每個變數都需要手寫型別。好的 TypeScript 會善用 inference,把型別寫在「contract boundary」而不是到處重複資訊。

2. Type checker 可以攔什麼?

function total(price: number, quantity: number): number {
  return price * quantity;
}

total("100", 2);
// type error

這個錯在 build / editor 階段就可看到,甚至 Browser 還沒拿到 JavaScript。

3. TypeScript 不能攔什麼?

type Course = {
  id: number;
  title: string;
};

const response = await fetch("/api/course/1");
const raw = await response.json();

// raw 是 runtime data
// Server 完全可能回:
// { "id": "oops", "title": null }

你在 source 裡宣告 Course,不會改變網路上的 JSON。Type system 只知道你告訴它的資訊,不會神奇地檢查 remote server。

4. any vs unknown:外部資料的安全邊界

let unsafe: any = await response.json();
unsafe.not.real.deep.value(); // 幾乎不阻止你

let raw: unknown = await response.json();
// raw.title // 不允許,先證明它的形狀
any

相當於對 type checker 說「這裡先不要管我」。

unknown

表示「我目前真的不知道它是什麼,請逼我先 narrowing / validate」。

5. Project checkpoint:Typed Course API Client v1

type Course = {
  id: number;
  title: string;
  score: number | null;
};

async function loadCourse(id: number): Promise<unknown> {
  const response = await fetch("/api/courses/" + id);

  if (!response.ok) {
    throw new Error("HTTP " + response.status);
  }

  return response.json();
}

這個版本故意回 Promise<unknown>。下一課才把 domain model 與 loading/error state 建完整。

6. Debug evidence:同一句「TypeScript 報錯」可能完全不同

EvidenceLayer例子
紅線 / tsc diagnostictype checkingstring 傳給 number parameter
SyntaxError / TypeError in BrowserJavaScript runtime外部資料 null,code 卻直接讀 property
HTTP 500server/network protocol不是 TypeScript compiler error

Knowledge check

  1. 為什麼 type Course = ... 不會自動驗證 JSON?
  2. 什麼情況適合讓 inference 自己工作?
  3. 為什麼外部 API data 用 unknown 通常比 any 好?
  4. 到本站 TypeScript Lab 實際比較 compile-time error 與能成功 emit 的 code。