五個你應(yīng)該了解的高級 TypeScript 類型體操
TypeScript 通過提供靜態(tài)類型系統(tǒng)改變了我們編寫 JavaScript 的方式,它幫助開發(fā)者早期捕捉錯誤并編寫更健壯的代碼。
但是,我們通常沒有充分發(fā)揮 TypeScript 的潛力。它不僅僅是定義簡單的類型和接口。
在這篇文章中,我們將討論 5 個高級 TypeScript API,它們將提升我們編寫 TypeScript 代碼的方式。
那么,讓我們開始吧!
Pick
TypeScript 中的 Pick 實(shí)用類型是一個強(qiáng)大的特性,它允許我們通過選擇現(xiàn)有類型的一個子集來構(gòu)造新的類型。
當(dāng)我們需要從復(fù)雜數(shù)據(jù)中獲取某些字段時,這非常有用。它有助于提高可讀性并增強(qiáng)類型安全性。
Pick 的語法是:
Pick<Type, Keys>;
- Type:這是我們將從中獲取屬性的原始類型。
- Keys:我們想要從類型中獲取的屬性。 (鍵由 | 分隔)
讓我們通過一個例子來理解它的用例:
假設(shè),在我們的應(yīng)用程序中有一個 BlogData 類型,如下所示:
type BlogData = {
title: 'string;';
description: 'string;';
author: string;
datePublished: string;
summary: string;
image?: string;
};
在顯示博客卡片時,我們只需要 title、author 和 datePublished 屬性。為此,我們可以使用 Pick 創(chuàng)建一個只包含所需屬性的新類型 BlogCardData:
type BlogCardData = Pick<BlogData, 'title' | 'author' | 'datePublished'>;
這里,BlogCardData 是一個包含 title、author 和 datePublished 屬性的新數(shù)據(jù)類型。它類似于以下類型:
type BlogCardData = {
title: 'string;';
author: string;
datePublished: string;
};
總體而言,Pick 允許我們明確指定函數(shù)或組件期望哪些屬性,從而編寫出更易于維護(hù)和更少出錯的代碼。
Partial
TypeScript 中的 Partial 實(shí)用類型用于通過使現(xiàn)有類型的全部屬性變?yōu)榭蛇x來創(chuàng)建新的類型。這在我們希望更新對象的部分屬性而無需提供整個對象時特別有用。
Partial 的語法是:
Partial<Type>;
- Type:這是我們要從中創(chuàng)建新類型并使所有屬性變?yōu)榭蛇x的原始類型。
讓我們通過一個例子來理解這一點(diǎn):
考慮我們之前展示的 BlogData 類型。
type BlogData = {
title: string;
description: string;
author: string;
datePublished: string;
summary: string;
image: string;
};
現(xiàn)在,我們希望使 summary、image 和 description 屬性變?yōu)榭蛇x的。為此,我們將同時使用 Pick 和 Partial,如下所示:
// 使用 Pick 創(chuàng)建所需屬性的新類型
type BlogPickData = Pick<Type, 'description' | 'summary' | 'image'>;
// 使用 Partial 使 BlogPickData 的所有屬性變?yōu)榭蛇x
type BlogOptionalData = Partial<BlogPickData>;
這里,我們首先創(chuàng)建了一個包含我們想要使可選的屬性的新數(shù)據(jù)類型 BlogPickData,然后使用 Partial 創(chuàng)建了 BlogOptionalData 類型來使這些屬性可選。
BlogOptionalData 類型類似于以下類型:
type BlogOptionalData = {
description: string;
summary: string;
image: string;
};
總體而言,Partial 允許我們創(chuàng)建更靈活的類型,用于更新操作,同時仍然保持類型安全性。
Readonly
顧名思義,Readonly 實(shí)用類型將給定類型的全部屬性變?yōu)橹蛔x。這意味著當(dāng)我們使用此類型創(chuàng)建對象時,我們不能重新分配它們。
這在編寫配置對象、常量或任何我們不希望以后更改的敏感數(shù)據(jù)時非常有用(以避免錯誤)。
Readonly 的語法是:
Readonly<Type>;
- Type:這是我們要將所有屬性轉(zhuǎn)換為只讀的原始類型。
讓我們通過一個例子來理解這一點(diǎn):
假設(shè),我們有一個應(yīng)用程序的配置設(shè)置的配置類型:
type Config {
endpoint: string;
apiKey: string;
}
現(xiàn)在我們將使用 Readonly 實(shí)用類型來使對象只讀。
const config: Readonly<Config> = {
endpoint: '<https://api.example.com>',
apiKey: 'arindam_1729',
};
這將確保 Config 對象在創(chuàng)建后不能被修改。如果嘗試修改對象,它將導(dǎo)致 TypeScript 錯誤。
注意:Readonly 實(shí)用類型確保屬性不能被更改,但僅在 TypeScript 級別。這意味著它是一個在編譯時工作的特性。TypeScript 編譯成的 JavaScript 沒有內(nèi)置的不可變性,因此 Readonly 規(guī)則在運(yùn)行時不適用。
總體而言,它有助于維護(hù)表示固定配置或常量的對象的完整性。
Exclude
Exclude 實(shí)用類型用于通過從聯(lián)合類型中排除某些不應(yīng)允許的成員來構(gòu)造類型。當(dāng)我們希望創(chuàng)建一個類型,它是另一個類型的子集,某些元素被移除時,這非常有用。
Exclude 的語法是:
Exclude<T, U>;
- T:這是我們將從中排除屬性的原始類型。
- U:我們想要從聯(lián)合類型中排除的屬性。
讓我們通過一個例子來理解這一點(diǎn):
假設(shè)我們有一個應(yīng)用程序,需要管理應(yīng)用程序中用戶角色的列表:
type UserRole = 'admin' | 'editor' | 'viewer' | 'guest';
并且我們希望在特定操作中排除某些角色。為此,我們將使用 Exclude 實(shí)用類型:
type AllowedRoles = Exclude<UserRole, 'guest' | 'viewer'>;
在這種情況下,AllowedRoles 是一個新創(chuàng)建的類型,包含 'admin' 和 'editor'。這類似于以下類型:
type AllowedRoles = 'admin' | 'editor';
總體而言,Exclude 允許我們?yōu)樘囟ㄓ美?xì)化類型定義,增強(qiáng)代碼中的類型安全性和清晰度。
Record & Map
Record 實(shí)用類型和 TypeScript 中的 Map 對象提供了兩種強(qiáng)大的方式來處理鍵值對集合。
Record 實(shí)用類型用于構(gòu)造一個具有給定類型 T 的屬性集 K 的類型。
Record 的語法是:
Record<K, T>;
- K:屬性集(鍵)。
- T:屬性的類型(值)。
讓我們通過一個例子來理解這一點(diǎn):
假設(shè),我們正在構(gòu)建一個管理用戶列表的應(yīng)用程序,用戶類型 User 如下:
type User {
id: string;
name: string;
}
現(xiàn)在,我們將使用 Record 類型來定義 Users 類型:
// 使用 Record 來為具有字符串鍵和 User 值的對象進(jìn)行類型定義
type Users = Record<string, User>;
這里,Record 創(chuàng)建了一個類型,其中鍵是字符串,值是 User 類型。
另一方面,TypeScript 中的 Map 對象(繼承自 JavaScript)是一個鍵值對的集合,其中鍵和值都可以是任何類型。
Map 的語法是:
Map<keyType, valueType>;
- keyType:映射中的鍵的類型(例如,string、number)。
- valueType:映射中的值的類型。
在前面的例子中,我們可以使用 Map 來實(shí)現(xiàn)這一點(diǎn):
type User {
id: string;
name: string;
}
// 初始化一個空的 Map,具有字符串鍵和 User 值
const usersMap = new Map<string, User>();
// 將用戶添加到 Map 中
usersMap.set('user1', { id: '1', name: 'Arindam' });
// 從 Map 中檢索用戶
const user = usersMap.get('user1');
Map 提供了像 .set 這樣的方法來添加鍵值對,以及像 .get 這樣的方法通過鍵檢索值。
總體而言,Record 和 Map 都增強(qiáng)了 TypeScript 處理數(shù)據(jù)集合的能力,同時保持類型安全性。
結(jié)論
如果你覺得這篇博文對你有幫助,請考慮將其分享給可能受益的其他人。你也可以關(guān)注我以獲取更多關(guān)于 JavaScript、React 和其他 Web 開發(fā)主題的內(nèi)容。