昨天我們學了 型別守衛(Type Guards),
今天來看看 TypeScript 內建的「型別小工具」。
它們能讓你不用重寫型別,就能快速得到你想要的型別變化。
Utility Types 是 TypeScript 內建的一組型別變換工具。你可以把它想成「型別的函式」,輸入一個型別,產生一個新型別。
好處:
Partial<T>
讓 T 的所有屬性變成可選的(?
)。
type User = { id: string; name: string; email: string };
type UserUpdate = Partial<User>;
// 等同於 { id?: string; name?: string; email?: string }
function updateUser(id: string, update: UserUpdate) {}
updateUser("u1", { name: "New Name" });
用途:更新部分資料(PATCH API)。
Required<T>
把所有可選屬性變成必填。
type User = { id?: string; name?: string };
type CompleteUser = Required<User>;
// { id: string; name: string }
用途:確保在某些流程後資料是完整的。
Readonly<T>
讓屬性不可修改。
type Config = { apiUrl: string; port: number };
const cfg: Readonly<Config> = { apiUrl: "https://api.com", port: 8080 };
cfg.port = 3000; // ❌ Cannot assign to 'port'
用途:防止意外修改設定物件。
Pick<T, K>
挑出 T 中的部分屬性。
type User = { id: string; name: string; email: string };
type UserPreview = Pick<User, "id" | "name">;
// { id: string; name: string }
用途:列表畫面只需要部分資料時。
Omit<T, K>
刪掉 T 中的某些屬性。
type User = { id: string; name: string; email: string };
type UserWithoutEmail = Omit<User, "email">;
// { id: string; name: string }
用途:過濾不必要或敏感資料。
Record<K, T>
建立一個以 K 為 key、T 為值的型別。
type Role = "admin" | "user" | "guest";
type Permissions = Record<Role, string[]>;
// { admin: string[]; user: string[]; guest: string[] }
用途:權限表、設定映射。
Exclude<T, U>
從 T 中排除掉 U。
type Status = "success" | "error" | "pending";
type Finished = Exclude<Status, "pending">;
// "success" | "error"
用途:移除不需要的型別成員。
Extract<T, U>
從 T 中挑出 U。
type Status = "success" | "error" | "pending";
type Active = Extract<Status, "pending">;
// "pending"
用途:篩選符合條件的型別成員。
NonNullable<T>
排除 null
與 undefined
。
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>;
// string
用途:在保證值不為空時使用。
ReturnType<T>
取得函式的回傳型別。
function getUser() {
return { id: "u1", name: "Alice" };
}
type User = ReturnType<typeof getUser>;
// { id: string; name: string }
用途:自動同步函式回傳型別與變數型別。
Parameters<T>
取得函式的參數型別(Tuple)。
function login(user: string, pass: string) {}
type LoginParams = Parameters<typeof login>;
// [user: string, pass: string]
用途:重用函式參數型別。
type User = { id: string; name: string; email: string; createdAt: Date };
// 更新 API 只接受部分資料
type UpdateUserDto = Partial<Omit<User, "id" | "createdAt">>;
function updateUser(id: string, data: UpdateUserDto) {
// ...
}
updateUser("u1", { name: "New Name" }); // OK
updateUser("u1", { createdAt: new Date() }); // ❌ createdAt 已被移除