Typescript中使用泛型約束的實現(xiàn)示例
在 TypeScript 中,泛型約束(Generic Constraints)用于限制泛型可以接受的類型范圍,確保泛型參數(shù)不是只能接受任意類型,而是只能接受滿足特定條件的類型。這既保留了泛型的靈活性,又增強了類型安全性。
為什么需要泛型約束?
默認情況下,泛型可以是任何類型,但有時你需要訪問類型的特定屬性或方法。如果不加以約束,TypeScript 無法保證這些屬性 / 方法存在,會導致類型錯誤。
例如,嘗試訪問泛型參數(shù)的 length 屬性:
// 錯誤示例:TypeScript 無法確定 T 有 length 屬性
function getLength<T>(arg: T): number {
return arg.length; // 報錯:Property 'length' does not exist on type 'T'
}這時就需要泛型約束來指定 T 必須包含 length 屬性。
如何使用泛型約束?
通過 extends 關(guān)鍵字可以實現(xiàn)泛型約束,語法為 <T extends 約束類型>。
1. 基礎(chǔ)約束:限制為特定結(jié)構(gòu)
最常見的約束是要求泛型必須包含某些屬性或方法。例如,約束 T 必須有 length 屬性:
// 定義一個接口作為約束條件
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)
// 錯誤用法:數(shù)字沒有 length 屬性
getLength(123); // 報錯:Argument of type 'number' is not assignable to parameter of type 'HasLength'2. 約束為另一個類型的子類型
可以約束泛型必須是另一個類型的子類型,例如約束 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" });
// 正確:擴展了 User 結(jié)構(gòu)(允許額外屬性)
getUserInfo({ id: 2, name: "Bob", age: 30 });
// 錯誤:缺少 name 屬性,不符合 User 結(jié)構(gòu)
getUserInfo({ id: 3 }); // 報錯:Property 'name' is missing3. 約束為 keyof 另一個類型(鍵約束)
使用 keyof 可以約束泛型必須是某個對象類型的鍵,常用于安全地訪問對象屬性:
// 約束 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)
// 錯誤:key 不是 person 的鍵
getProperty(person, "height"); // 報錯:Argument of type '"height"' is not assignable to parameter of type '"name" | "age"'4. 多個約束(交叉類型)
如果需要同時滿足多個約束,可以使用交叉類型(&)組合多個條件:
interface HasLength {
length: number;
}
interface HasName {
name: string;
}
// 約束 T 必須同時滿足 HasLength 和 HasName
function getInfo<T extends HasLength & HasName>(obj: T): string {
return `Name: ${obj.name}, Length: ${obj.length}`;
}
// 正確:同時有 name 和 length
getInfo({ name: "Test", length: 10 });
// 錯誤:缺少 length
getInfo({ name: "Test" }); // 報錯:Property 'length' is missing總結(jié)
泛型約束的核心是通過 extends 關(guān)鍵字限制泛型的范圍,常見用法包括:
1.約束為包含特定屬性 / 方法的結(jié)構(gòu)
2.約束為另一個類型的子類型
3.結(jié)合 keyof 約束為對象的鍵
4.多個約束的組合(交叉類型)
通過泛型約束,既能保留泛型的靈活性,又能確保代碼在編譯時的類型安全,避免運行時錯誤。
到此這篇關(guān)于Typescript中使用泛型約束的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)Typescript 泛型約束內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript 中 JSON.parse 函數(shù) 和 JSON.stringify 函數(shù)
這篇文章主要介紹了JavaScript -- JSON.parse 函數(shù) 和 JSON.stringify 函數(shù),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12
JS 在數(shù)組插入字符的實現(xiàn)代碼(可參考JavaScript splice() 方法)
在數(shù)組插入字符,添加數(shù)組,刪除數(shù)組可以用slice自帶的方法。操作比較方便,這個代碼是作者通過push與shift方法實現(xiàn),只能是個思路,但不推薦這樣的方法。2009-12-12
用循環(huán)或if語句從json中取數(shù)據(jù)示例
倘若想將id和pid數(shù)據(jù)依次取出,就只能用循環(huán),若想有選擇性的輸出時,需要添加if條件2014-08-08
JavaScript通過mouseover()實現(xiàn)圖片變大效果的示例
下面小編就為大家分享一篇JavaScript通過mouseover()實現(xiàn)圖片變大效果的示例,具有很好的參考價值,希望對大家有所幫助2017-12-12
使用Layer組件彈出多個對話框(非嵌套)與關(guān)閉及刷新的例子
今天小編就為大家分享一篇使用Layer組件彈出多個對話框(非嵌套)與關(guān)閉及刷新的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

