網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、泛型函數(shù)
TypeScript
泛型是一種可以使代碼具有更高的可重用性和泛化能力的特性。通過(guò)泛型,我們可以定義一種通用的類型或函數(shù),使其能夠應(yīng)對(duì)多種類型的輸入。泛型在類、函數(shù)、接口等多種場(chǎng)景下都可以使用。
具體來(lái)說(shuō),在定義泛型函數(shù)時(shí),我們可以使用來(lái)表示一個(gè)類型變量,這樣我們就可以在函數(shù)中使用這個(gè)泛型類型來(lái)作為參數(shù)類型、返回值類型或變量類型等。例如:
function echo<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = echo;
在這個(gè)例子中,我們定義了一個(gè)echo函數(shù),它使用泛型類型變量T作為輸入?yún)?shù)類型和返回值類型,這樣我們就可以使用不同類型的參數(shù)來(lái)調(diào)用該函數(shù),例如:
console.log(echo('Hello TypeScript!')); // 輸出:Hello TypeScript!
console.log(echo(123)); // 輸出:123
二、泛型類
在類的定義中使用泛型,也可以大大提高代碼的復(fù)用性和靈活性。例如下面的代碼:
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());
在上面的代碼中,定義了一個(gè)Stack類,并聲明了泛型類型T,用于在push和pop方法中進(jìn)行類型的轉(zhuǎn)換。通過(guò)傳入不同類型的參數(shù),可以得到不同類型的Stack實(shí)例。
三、泛型接口
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) {
// 添加鍵值對(duì)
},
get(key: number): string | undefined {
// 獲取鍵值對(duì)
},
has(key: number): boolean {
// 判斷是否存在
},
clear() {
// 清空Map
}
};
numMap.set(1, 'apple');
numMap.set(2, 'banana');
console.log(numMap.get(1));
console.log(numMap.get(2));
在上面的代碼中,定義了一個(gè)Map接口,并使用泛型K和V來(lái)約束鍵和值的類型。通過(guò)傳入不同類型的參數(shù),可以得到不同類型的Map實(shí)例,并實(shí)現(xiàn)對(duì)不同類型鍵值對(duì)的操作。
四、泛型約束、泛型限制用法<T> extends {屬性:類型}
在 TypeScript 中,泛型約束是一種讓泛型類型參數(shù)只能取某些特定類型的值的機(jī)制。這個(gè)特定類型的限制可以是一個(gè)接口、類、枚舉或其他類型。
例如,假設(shè)我們有一個(gè)泛型函數(shù),它接受一個(gè)類型參數(shù) T 和一個(gè)對(duì)象參數(shù) obj,這個(gè)函數(shù)返回 obj 中的第一個(gè) 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.`);
}
但是,這個(gè)函數(shù)可能會(huì)遇到一些問(wèn)題。例如,如果我們調(diào)用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),那么會(huì)拋出一個(gè)錯(cuò)誤,因?yàn)樽址?‘1’ 不是一個(gè) number 類型。
為了解決這個(gè)問(wèn)題,我們可以使用泛型約束來(lái)限制 T 只能取某些特定類型的值。例如,我們可以要求 T 必須是實(shí)現(xiàn)了 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.`);
}
現(xiàn)在,如果我們調(diào)用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),就會(huì)得到一個(gè)類型錯(cuò)誤,因?yàn)?‘1’ 不是一個(gè)實(shí)現(xiàn)了 Number 接口的類型。但是,如果我們調(diào)用 getPropertyValue({ a: 1, b: 2, c: 3 }),就能得到正確的結(jié)果了。
另一泛型約束\<key extends keyof Type>
在 TypeScript 中,<key extends keyof Type>
是一種泛型約束方式,用于限制一個(gè)泛型類型參數(shù) key
的范圍。
其中,keyof
關(guān)鍵字可以用于獲取一個(gè)類型 Type
的所有屬性名,返回一個(gè)字符串字面量類型,例如:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
在 <key extends keyof Type>
中,extends
關(guān)鍵字表示限制 key
的取值只能是 Type
類型中已有的屬性名。也就是說(shuō),只有 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'); // 編譯報(bào)錯(cuò),gender 不是 person 中的屬性
在上面的例子中,getValueByKey
函數(shù)接收兩個(gè)參數(shù):一個(gè)泛型類型參數(shù) T
,代表輸入對(duì)象的類型;一個(gè)泛型類型參數(shù) K
,代表屬性名的類型。
extends keyof T
約束了類型參數(shù) K
必須是輸入對(duì)象類型 T
中已存在的屬性名。因此,調(diào)用 getValueByKey
函數(shù)傳入一個(gè)不存在的屬性名 gender
會(huì)引發(fā)編譯錯(cuò)誤。
五、使用泛型注意點(diǎn)
在編寫泛型方法時(shí),應(yīng)該注意以下幾點(diǎn):
- 泛型形參的名稱應(yīng)該描述清楚其作用和范圍,盡量不要使用單個(gè)字母的形參名稱;
- 在使用泛型類型的屬性或方法時(shí),應(yīng)該確保該屬性或方法在所有可能的泛型類型中都是存在的,不要使用不存在的屬性或方法;
- 在使用泛型類型的操作符時(shí),應(yīng)該考慮不同類型之間可能的差異性和兼容性問(wèn)題,避免出現(xiàn)類型錯(cuò)誤
原文鏈接:https://blog.csdn.net/jieyucx/article/details/131346916
- 上一篇:沒(méi)有了
- 下一篇:沒(méi)有了
相關(guān)推薦
- 2021-12-14 go調(diào)用shell命令兩種方式實(shí)現(xiàn)(有無(wú)返回值)_Golang
- 2022-06-02 Python進(jìn)程池基本概念_python
- 2022-03-20 C語(yǔ)言初階之?dāng)?shù)組詳細(xì)介紹_C 語(yǔ)言
- 2022-05-18 python中l(wèi)eastsq函數(shù)的使用方法_python
- 2022-12-11 C語(yǔ)言執(zhí)行時(shí),程序控制臺(tái)輸出窗口?一閃而過(guò)問(wèn)題及解決_C 語(yǔ)言
- 2023-04-22 GO的range如何使用詳解_Golang
- 2022-10-31 關(guān)于Golang標(biāo)準(zhǔn)庫(kù)flag的全面講解_Golang
- 2022-07-10 詳解HashMap并發(fā)修改異常
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支