網站首頁 編程語言 正文
一、泛型函數
TypeScript
泛型是一種可以使代碼具有更高的可重用性和泛化能力的特性。通過泛型,我們可以定義一種通用的類型或函數,使其能夠應對多種類型的輸入。泛型在類、函數、接口等多種場景下都可以使用。
具體來說,在定義泛型函數時,我們可以使用來表示一個類型變量,這樣我們就可以在函數中使用這個泛型類型來作為參數類型、返回值類型或變量類型等。例如:
function echo<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = echo;
在這個例子中,我們定義了一個echo函數,它使用泛型類型變量T作為輸入參數類型和返回值類型,這樣我們就可以使用不同類型的參數來調用該函數,例如:
console.log(echo('Hello TypeScript!')); // 輸出:Hello TypeScript!
console.log(echo(123)); // 輸出:123
二、泛型類
在類的定義中使用泛型,也可以大大提高代碼的復用性和靈活性。例如下面的代碼:
class Stack<T> {
private items: T[] = [];
push(item: T) {
this.items.push(item);
}
pop(): T {
return this.items.pop();
}
}
let strStack = new Stack<string>();
strStack.push('apple');
strStack.push('banana');
strStack.push('cherry');
console.log(strStack.pop());
console.log(strStack.pop());
console.log(strStack.pop());
在上面的代碼中,定義了一個Stack類,并聲明了泛型類型T,用于在push和pop方法中進行類型的轉換。通過傳入不同類型的參數,可以得到不同類型的Stack實例。
三、泛型接口
interface Map<K, V> {
set(key: K, val: V): void;
get(key: K): V | undefined;
has(key: K): boolean;
clear(): void;
}
let numMap: Map<number, string> = {
set(key: number, val: string) {
// 添加鍵值對
},
get(key: number): string | undefined {
// 獲取鍵值對
},
has(key: number): boolean {
// 判斷是否存在
},
clear() {
// 清空Map
}
};
numMap.set(1, 'apple');
numMap.set(2, 'banana');
console.log(numMap.get(1));
console.log(numMap.get(2));
在上面的代碼中,定義了一個Map接口,并使用泛型K和V來約束鍵和值的類型。通過傳入不同類型的參數,可以得到不同類型的Map實例,并實現對不同類型鍵值對的操作。
四、泛型約束、泛型限制用法<T> extends {屬性:類型}
在 TypeScript 中,泛型約束是一種讓泛型類型參數只能取某些特定類型的值的機制。這個特定類型的限制可以是一個接口、類、枚舉或其他類型。
例如,假設我們有一個泛型函數,它接受一個類型參數 T 和一個對象參數 obj,這個函數返回 obj 中的第一個 T 類型的屬性值:
function getPropertyValue<T>(obj: object): T {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
let value = obj[key];
if (value instanceof T) {
return value;
}
}
}
throw new Error(`No property of type ${T.name} found.`);
}
但是,這個函數可能會遇到一些問題。例如,如果我們調用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),那么會拋出一個錯誤,因為字符串 ‘1’ 不是一個 number 類型。
為了解決這個問題,我們可以使用泛型約束來限制 T 只能取某些特定類型的值。例如,我們可以要求 T 必須是實現了 Number 接口的類型:
interface Number {
new (value?: any): number;
(value?: any): number;
readonly NaN: number;
readonly MAX_VALUE: number;
readonly MIN_VALUE: number;
readonly NEGATIVE_INFINITY: number;
readonly POSITIVE_INFINITY: number;
}
function getPropertyValue<T extends Number>(obj: object): T {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
let value = obj[key];
if (value instanceof T) {
return value;
}
}
}
throw new Error(`No property of type ${T.name} found.`);
}
現在,如果我們調用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),就會得到一個類型錯誤,因為 ‘1’ 不是一個實現了 Number 接口的類型。但是,如果我們調用 getPropertyValue({ a: 1, b: 2, c: 3 }),就能得到正確的結果了。
另一泛型約束\<key extends keyof Type>
在 TypeScript 中,<key extends keyof Type>
是一種泛型約束方式,用于限制一個泛型類型參數 key
的范圍。
其中,keyof
關鍵字可以用于獲取一個類型 Type
的所有屬性名,返回一個字符串字面量類型,例如:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
在 <key extends keyof Type>
中,extends
關鍵字表示限制 key
的取值只能是 Type
類型中已有的屬性名。也就是說,只有 key
取值為 Type
類型中已有的屬性名才符合類型約束,例如:
function getValueByKey<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person = {
name: 'Bob',
age: 25,
};
const name = getValueByKey(person, 'name'); // name 的類型是 string
const age = getValueByKey(person, 'age'); // age 的類型是 number
const gender = getValueByKey(person, 'gender'); // 編譯報錯,gender 不是 person 中的屬性
在上面的例子中,getValueByKey
函數接收兩個參數:一個泛型類型參數 T
,代表輸入對象的類型;一個泛型類型參數 K
,代表屬性名的類型。
extends keyof T
約束了類型參數 K
必須是輸入對象類型 T
中已存在的屬性名。因此,調用 getValueByKey
函數傳入一個不存在的屬性名 gender
會引發編譯錯誤。
五、使用泛型注意點
在編寫泛型方法時,應該注意以下幾點:
- 泛型形參的名稱應該描述清楚其作用和范圍,盡量不要使用單個字母的形參名稱;
- 在使用泛型類型的屬性或方法時,應該確保該屬性或方法在所有可能的泛型類型中都是存在的,不要使用不存在的屬性或方法;
- 在使用泛型類型的操作符時,應該考慮不同類型之間可能的差異性和兼容性問題,避免出現類型錯誤
原文鏈接:https://blog.csdn.net/jieyucx/article/details/131346916
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-10-05 Android開發Activity毛玻璃背景效果_Android
- 2022-06-22 git工作區暫存區與版本庫基本理解及提交流程全解_其它綜合
- 2022-07-15 教你docker方式部署nacos_docker
- 2022-08-28 failed to configure a datasource: ‘url‘ attribute
- 2022-08-03 python數據類型可變與不可變深入分析_python
- 2024-03-01 【uniapp】uniapp中刷新本頁面
- 2022-02-13 Chrome控制臺報錯:無法加載 SourceMap 錯誤:狀態代碼 404,net::ERR_HT
- 2023-07-04 Netty的SO_LINGER不要隨便用
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支