TypeScript 宣告
TypeScript 在宣告時用「冒號 :」加上型別來做型別註記(type annotation):
const x: number = 5;
let name: string = "Tom";
很多時候不用手動寫,TypeScript 會**型別推斷(type inference)**自動推出:const x = 5 就已經是 number。
宣告物件型別:interface 與 type
複雜的型別可以用 interface 或 type 來命名後重複使用:
interface Person {
name: string;
age: number;
}
type Animal = {
name: string;
legs: number;
};
const tom: Person = { name: "Tom", age: 18 };
兩者大部分情境可互換,主要差異:
interface | type | |
|---|---|---|
| 擴充方式 | extends 繼承 | & 交集(intersection) |
| 宣告合併 | ✅ 同名會自動合併 | ❌ 同名會報錯 |
| 適用範圍 | 只能描述物件 / class 形狀 | 任何型別(union、tuple、primitive 別名…) |
經驗法則:描述物件或要被 class implements 用 interface;需要 union(type Status = "ok" | "error")或別名用 type。
泛型(Generics)
泛型才是用 < > 的地方 —— 它讓型別像「參數」一樣傳入,寫出對多種型別都通用、又不丟失型別資訊的程式碼:
function identity<T>(x: T): T {
return x;
}
const a = identity<number>(5); // a 是 number
const b = identity("hello"); // T 推斷成 string,b 是 string
T 是型別變數,呼叫時才決定實際型別。也能用在 interface / type 上:
interface Box<T> {
value: T;
}
const numBox: Box<number> = { value: 5 };
可用 extends 對泛型加約束,例如 <T extends { id: number }> 限制 T 必須有 id。
常用 Utility Types
TypeScript 內建一批根據既有型別衍生新型別的工具:
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>; // 所有欄位變成 optional
type UserName = Pick<User, "name">; // 只取 name 欄位
type IdToName = Record<number, string>; // { [key: number]: string }
Partial<T>:把T的所有屬性變成可選,常用於更新(patch)場景。Pick<T, K>:只挑出T中指定的幾個 key。Record<K, V>:建立 key 為K、value 為V的物件型別。
其他常見的還有 Omit、Required、Readonly,都是建立在泛型之上的衍生型別。