TypeScript
是現代 JavaScript
開發中不可或缺的工具,它提供了類型安全和豐富的特性。許多開發者掌握了基本用法,但還有一些鮮為人知的技巧可以讓你的代碼更高效、干凈且易于維護。接下來,讓我們深入探討每位開發者應該了解的20個 TypeScript
技巧,附帶示例和實用建議!
-
非空類型 (
NonNullable
)NonNullable
工具類型可以消除類型中的null
和undefined
,幫助你避免空值問題。type User = { name: string; age?: number | null }; const user: NonNullable<User["age"]> = 30; // 不允許 null 或 undefined
-
使用
Partial
增強靈活性Partial<T>
將類型中的所有屬性設為可選,非常適合更新對象字段的子集。interface User { name: string; age: number; email: string; } const updateUser = (user: Partial<User>) => { return { ...user, updatedAt: new Date() }; }; updateUser({ name: 'John' }); // 不需提供完整對象
-
利用
Readonly
實現不可變數據Readonly<T>
將類型的所有屬性設為只讀,防止修改。const config: Readonly<{ apiUrl: string; retries: number }> = { apiUrl: 'https://api.example.com', retries: 5 }; // config.apiUrl = 'https://newapi.com'; // 錯誤:只讀屬性
-
映射類型實現動態屬性類型
映射類型允許通過轉換已有類型創建新類型,非常適合創建對象類型變體。
type Status = 'loading' | 'success' | 'error'; type ApiResponse<T> = { [K in Status]: T; }; const response: ApiResponse<string> = { loading: '加載中...', success: '數據加載成功', error: '出現錯誤' };
-
帶可選元素的元組類型
TypeScript
支持在元組中使用可選元素,適合處理變參函數。type UserTuple = [string, number?, boolean?]; const user1: UserTuple = ['Alice']; // 僅名字 const user2: UserTuple = ['Bob', 30]; // 名字和年齡 const user3: UserTuple = ['Charlie', 25, true]; // 完整元組
-
使用聯合類型進行全面檢查
在
switch
語句中確保處理所有聯合類型情況,以避免遺漏。type Status = 'open' | 'closed' | 'pending'; function handleStatus(status: Status) { switch (status) { case 'open': return '已打開'; case 'closed': return '已關閉'; case 'pending': return '待處理'; default: const exhaustiveCheck: never = status; // 未處理的狀態類型會報錯 return exhaustiveCheck; } }
-
使用
Omit
排除鍵使用
Omit
創建一個排除特定鍵的對象類型,方便管理。interface Todo { title: string; description: string; completed: boolean; } type TodoPreview = Omit<Todo, 'description'>; const todo: TodoPreview = { title: '學習 TypeScript', completed: false };
-
使用
in
和instanceof
進行類型細化利用
in
和instanceof
在運行時細化類型,確保代碼安全。function processInput(input: string | number | { title: string }) { if (typeof input === 'string') { return input.toUpperCase(); // 細化為字符串 } else if (typeof input === 'number') { return input * 2; // 細化為數字 } else if ('title' in input) { return input.title; // 細化為對象 } }
-
使用條件類型實現高級類型邏輯
條件類型提供了靈活的類型轉換。
type IsString<T> = T extends string ? true : false; type CheckString = IsString<'Hello'>; // true type CheckNumber = IsString<42>; // false
-
使用
as const
凍結字面量類型as const
可以確保值被視為字面量類型,避免可變性。const COLORS = ['red', 'green', 'blue'] as const; type Color = typeof COLORS[number]; // 'red' | 'green' | 'blue'
-
使用
Extract
和Exclude
精煉類型通過
Extract
和Exclude
從聯合類型中選擇或過濾類型。type T = 'a' | 'b' | 'c'; type OnlyAOrB = Extract<T, 'a' | 'b'>; // 'a' | 'b' type ExcludeC = Exclude<T, 'c'>; // 'a' | 'b'
-
自定義類型保護
創建類型保護函數以動態精確化類型。
function isString(input: any): input is string { return typeof input === 'string'; } const value: any = 'Hello'; if (isString(value)) { console.log(value.toUpperCase()); // 安全:value 是字符串 }
-
使用
Record
創建動態對象類型Record<K, V>
適合創建具有動態鍵的對象類型。type Role = 'admin' | 'user' | 'guest'; const permissions: Record<Role, string[]> = { admin: ['read', 'write', 'delete'], user: ['read', 'write'], guest: ['read'] };
-
動態類屬性與索引簽名
索引簽名可以讓你創建具有動態屬性名的對象或類。
class DynamicObject { [key: string]: any; } const obj = new DynamicObject(); obj.name = 'Alice'; obj.age = 30;
-
使用
never
類型表示不可能的狀態never
類型表示不應出現的值,通常用于全面檢查。function assertNever(value: never): never { throw new Error(`意外的值: ${value}`); }
-
可選鏈用于安全屬性訪問
可選鏈(
?.
)可以安全訪問深層嵌套的屬性。const user = { profile: { name: 'John' } }; const userName = user?.profile?.name; // 'John' const age = user?.profile?.age ?? '未提供'; // 默認值
-
空值合并運算符(
??
)使用空值合并運算符提供默認值,僅在值為
null
或undefined
時生效。const input: string | null = null; const defaultValue = input ?? '默認值'; // '默認值'
-
使用
ReturnType
推斷返回類型ReturnType<T>
可以提取函數的返回類型,處理復雜類型時十分有用。function getUser() { return { name: 'John', age: 30 }; } type UserReturn = ReturnType<typeof getUser>; // { name: string; age: number; }
-
函數中的類型參數
泛型類型參數使函數在不同類型間更靈活。
function identity<T>(value: T): T { return value; } identity<string>('Hello'); // 'Hello' identity<number>(42); // 42
-
交叉類型用于合并結構
交叉類型允許將多個類型合并為一個。
type Admin = { privileges: string[] }; type User = { name: string }; type AdminUser = Admin & User; const adminUser: AdminUser = { privileges: ['admin', 'editor'], name: 'Alice' };
這些技巧將幫助你將 TypeScript
技能提升到新層次!?? 嘗試將這些模式融入到你的項目中,以獲得更清晰、高效的代碼。