Typescript中使用泛型約束的實(shí)現(xiàn)示例
在 TypeScript 中,泛型約束(Generic Constraints)用于限制泛型可以接受的類型范圍,確保泛型參數(shù)不是只能接受任意類型,而是只能接受滿足特定條件的類型。這既保留了泛型的靈活性,又增強(qiáng)了類型安全性。
為什么需要泛型約束?
默認(rèn)情況下,泛型可以是任何類型,但有時(shí)你需要訪問類型的特定屬性或方法。如果不加以約束,TypeScript 無法保證這些屬性 / 方法存在,會(huì)導(dǎo)致類型錯(cuò)誤。
例如,嘗試訪問泛型參數(shù)的 length 屬性:
// 錯(cuò)誤示例:TypeScript 無法確定 T 有 length 屬性
function getLength<T>(arg: T): number {
return arg.length; // 報(bào)錯(cuò):Property 'length' does not exist on type 'T'
}這時(shí)就需要泛型約束來指定 T 必須包含 length 屬性。
如何使用泛型約束?
通過 extends 關(guān)鍵字可以實(shí)現(xiàn)泛型約束,語法為 <T extends 約束類型>。
1. 基礎(chǔ)約束:限制為特定結(jié)構(gòu)
最常見的約束是要求泛型必須包含某些屬性或方法。例如,約束 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)在可以安全訪問 length 了
}
// 正確用法:字符串、數(shù)組等有 length 屬性的類型
getLength("hello"); // 5(字符串有 length)
getLength([1, 2, 3]); // 3(數(shù)組有 length)
// 錯(cuò)誤用法:數(shù)字沒有 length 屬性
getLength(123); // 報(bào)錯(cuò):Argument of type 'number' is not assignable to parameter of type 'HasLength'2. 約束為另一個(gè)類型的子類型
可以約束泛型必須是另一個(gè)類型的子類型,例如約束 T 必須是 User 類型的子類型:
interface User {
id: number;
name: string;
}
// 約束 T 必須是 User 的子類型(即必須包含 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è)類型(鍵約束)
使用 keyof 可以約束泛型必須是某個(gè)對(duì)象類型的鍵,常用于安全地訪問對(duì)象屬性:
// 約束 K 必須是 T 的鍵(keyof T 返回 T 所有鍵的聯(lián)合類型)
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]; // 安全訪問 obj 的屬性
}
const person = { name: "Alice", age: 25 };
// 正確:key 是 person 的有效鍵
getProperty(person, "name"); // "Alice"(類型:string)
getProperty(person, "age"); // 25(類型: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è)約束(交叉類型)
如果需要同時(shí)滿足多個(gè)約束,可以使用交叉類型(&)組合多個(gè)條件:
interface HasLength {
length: number;
}
interface HasName {
name: string;
}
// 約束 T 必須同時(shí)滿足 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é)
泛型約束的核心是通過 extends 關(guān)鍵字限制泛型的范圍,常見用法包括:
1.約束為包含特定屬性 / 方法的結(jié)構(gòu)
2.約束為另一個(gè)類型的子類型
3.結(jié)合 keyof 約束為對(duì)象的鍵
4.多個(gè)約束的組合(交叉類型)
通過泛型約束,既能保留泛型的靈活性,又能確保代碼在編譯時(shí)的類型安全,避免運(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à)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助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)頁中經(jīng)常需要輸入正確的身份證號(hào)碼,只能通過程序來驗(yàn)證身份證格式。根據(jù)身份證號(hào)碼生成的原理,就是驗(yàn)證后面幾位就可以了。2009-11-11
利用momentJs做一個(gè)倒計(jì)時(shí)組件(實(shí)例代碼)
這篇文章主要介紹了利用momentJs做一個(gè)倒計(jì)時(shí)組件,本文通過實(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

