Typescript中使用泛型約束的實(shí)現(xiàn)示例
在 TypeScript 中,泛型約束(Generic Constraints)用于限制泛型可以接受的類(lèi)型范圍,確保泛型參數(shù)不是只能接受任意類(lèi)型,而是只能接受滿(mǎn)足特定條件的類(lèi)型。這既保留了泛型的靈活性,又增強(qiáng)了類(lèi)型安全性。
為什么需要泛型約束?
默認(rèn)情況下,泛型可以是任何類(lèi)型,但有時(shí)你需要訪(fǎng)問(wèn)類(lèi)型的特定屬性或方法。如果不加以約束,TypeScript 無(wú)法保證這些屬性 / 方法存在,會(huì)導(dǎo)致類(lèi)型錯(cuò)誤。
例如,嘗試訪(fǎng)問(wèn)泛型參數(shù)的 length 屬性:
// 錯(cuò)誤示例:TypeScript 無(wú)法確定 T 有 length 屬性
function getLength<T>(arg: T): number {
return arg.length; // 報(bào)錯(cuò):Property 'length' does not exist on type 'T'
}這時(shí)就需要泛型約束來(lái)指定 T 必須包含 length 屬性。
如何使用泛型約束?
通過(guò) extends 關(guān)鍵字可以實(shí)現(xiàn)泛型約束,語(yǔ)法為 <T extends 約束類(lèi)型>。
1. 基礎(chǔ)約束:限制為特定結(jié)構(gòu)
最常見(jiàn)的約束是要求泛型必須包含某些屬性或方法。例如,約束 T 必須有 length 屬性:
// 定義一個(gè)接口作為約束條件
interface HasLength {
length: number;
}
// 使用 extends 約束 T 必須符合 HasLength 結(jié)構(gòu)
function getLength<T extends HasLength>(arg: T): number {
return arg.length; // 現(xiàn)在可以安全訪(fǎng)問(wèn) length 了
}
// 正確用法:字符串、數(shù)組等有 length 屬性的類(lèi)型
getLength("hello"); // 5(字符串有 length)
getLength([1, 2, 3]); // 3(數(shù)組有 length)
// 錯(cuò)誤用法:數(shù)字沒(méi)有 length 屬性
getLength(123); // 報(bào)錯(cuò):Argument of type 'number' is not assignable to parameter of type 'HasLength'2. 約束為另一個(gè)類(lèi)型的子類(lèi)型
可以約束泛型必須是另一個(gè)類(lèi)型的子類(lèi)型,例如約束 T 必須是 User 類(lèi)型的子類(lèi)型:
interface User {
id: number;
name: string;
}
// 約束 T 必須是 User 的子類(lèi)型(即必須包含 id 和 name)
function getUserInfo<T extends User>(user: T): string {
return `ID: ${user.id}, Name: ${user.name}`;
}
// 正確:符合 User 結(jié)構(gòu)
getUserInfo({ id: 1, name: "Alice" });
// 正確:擴(kuò)展了 User 結(jié)構(gòu)(允許額外屬性)
getUserInfo({ id: 2, name: "Bob", age: 30 });
// 錯(cuò)誤:缺少 name 屬性,不符合 User 結(jié)構(gòu)
getUserInfo({ id: 3 }); // 報(bào)錯(cuò):Property 'name' is missing3. 約束為 keyof 另一個(gè)類(lèi)型(鍵約束)
使用 keyof 可以約束泛型必須是某個(gè)對(duì)象類(lèi)型的鍵,常用于安全地訪(fǎng)問(wèn)對(duì)象屬性:
// 約束 K 必須是 T 的鍵(keyof T 返回 T 所有鍵的聯(lián)合類(lèi)型)
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]; // 安全訪(fǎng)問(wèn) obj 的屬性
}
const person = { name: "Alice", age: 25 };
// 正確:key 是 person 的有效鍵
getProperty(person, "name"); // "Alice"(類(lèi)型:string)
getProperty(person, "age"); // 25(類(lèi)型:number)
// 錯(cuò)誤:key 不是 person 的鍵
getProperty(person, "height"); // 報(bào)錯(cuò):Argument of type '"height"' is not assignable to parameter of type '"name" | "age"'4. 多個(gè)約束(交叉類(lèi)型)
如果需要同時(shí)滿(mǎn)足多個(gè)約束,可以使用交叉類(lèi)型(&)組合多個(gè)條件:
interface HasLength {
length: number;
}
interface HasName {
name: string;
}
// 約束 T 必須同時(shí)滿(mǎn)足 HasLength 和 HasName
function getInfo<T extends HasLength & HasName>(obj: T): string {
return `Name: ${obj.name}, Length: ${obj.length}`;
}
// 正確:同時(shí)有 name 和 length
getInfo({ name: "Test", length: 10 });
// 錯(cuò)誤:缺少 length
getInfo({ name: "Test" }); // 報(bào)錯(cuò):Property 'length' is missing總結(jié)
泛型約束的核心是通過(guò) extends 關(guān)鍵字限制泛型的范圍,常見(jiàn)用法包括:
1.約束為包含特定屬性 / 方法的結(jié)構(gòu)
2.約束為另一個(gè)類(lèi)型的子類(lèi)型
3.結(jié)合 keyof 約束為對(duì)象的鍵
4.多個(gè)約束的組合(交叉類(lèi)型)
通過(guò)泛型約束,既能保留泛型的靈活性,又能確保代碼在編譯時(shí)的類(lèi)型安全,避免運(yùn)行時(shí)錯(cuò)誤。
到此這篇關(guān)于Typescript中使用泛型約束的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Typescript 泛型約束內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)電商平臺(tái)商品細(xì)節(jié)圖
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)電商平臺(tái)商品細(xì)節(jié)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
使用JavaScript和CSS實(shí)現(xiàn)文本隔行換色的方法
這篇文章主要介紹了使用JavaScript和CSS實(shí)現(xiàn)文本隔行換色的方法,當(dāng)然最普通的也可以單純用CSS實(shí)現(xiàn),需要的朋友可以參考下2015-11-11
詳解JavaScript對(duì)象轉(zhuǎn)原始值
這篇文章主要為大家介紹了vue組件通信的幾種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2021-12-12
原生js FileReader對(duì)象實(shí)現(xiàn)圖片上傳本地預(yù)覽效果
這篇文章主要介紹了原生js FileReader對(duì)象實(shí)現(xiàn)圖片上傳本地預(yù)覽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
javascript或asp實(shí)現(xiàn)的判斷身份證號(hào)碼是否正確兩種驗(yàn)證方法
在網(wǎng)頁(yè)中經(jīng)常需要輸入正確的身份證號(hào)碼,只能通過(guò)程序來(lái)驗(yàn)證身份證格式。根據(jù)身份證號(hào)碼生成的原理,就是驗(yàn)證后面幾位就可以了。2009-11-11
利用momentJs做一個(gè)倒計(jì)時(shí)組件(實(shí)例代碼)
這篇文章主要介紹了利用momentJs做一個(gè)倒計(jì)時(shí)組件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
webpack 自動(dòng)清理 dist 文件夾的兩種實(shí)現(xiàn)方法
這篇文章主要介紹了webpack 自動(dòng)清理 dist 文件夾的兩種實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06

