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