大家好,我是王天~
這篇文章是 ts入門指南系列中第四篇,主要講解ts中的泛型應(yīng)用,泛型在ts中是比較重要的概念,我花挺長時(shí)間才搞明白的,希望能幫助到大家 ~
** ts 入門指南系列 **
- Ts和Js 誰更適合前端開發(fā)?| typescript 入門指南 01
- 詳解tsconfig.json 配置文件 | 02 ts入門指南
- ts基礎(chǔ)使用-語法類型 | typescript入門指南 03
1. 前言
我們可以把泛型比喻為一個(gè)類型占位符,它告訴編譯器:“嘿,這里有一個(gè)類型參數(shù),我現(xiàn)在不確定具體是什么類型,但稍后會(huì)告訴你?!?/p>
通過使用泛型,我們可以編寫更靈活、更可復(fù)用的代碼。它允許我們在定義函數(shù)、類或接口時(shí)使用類型占位符來表示類型,而不直接指定具體的類型。這樣,在實(shí)際使用時(shí),我們可以傳入不同的類型參數(shù),使得代碼可以適用于多種情況。
例如,讓我們看一個(gè)簡單的例子,來解釋泛型的使用。假設(shè)我們有一個(gè)名為 identity
的函數(shù),它接受一個(gè)參數(shù)并返回該參數(shù):
function identity<T>(value: T): T {
return value;
}
圖片來源網(wǎng)絡(luò)
在上述代碼中,<T>
表示這是一個(gè)泛型函數(shù),T
是一個(gè)類型參數(shù),可以是任何類型。函數(shù)的參數(shù) arg
的類型為 T
,返回值的類型也是 T
。
這樣,我們可以在函數(shù)調(diào)用時(shí)傳入不同的類型參數(shù),使得函數(shù)適用于各種類型的參數(shù)。
例如,我們可以這樣調(diào)用 identity
函數(shù):
let result1 = identity<number>(42); // 傳入 number 類型
let result2 = identity<string>("Hello, TypeScript"); // 傳入 string 類型
在第一次調(diào)用時(shí),類型參數(shù) number
被傳遞給 identity
函數(shù),所以返回值的類型也是 number
。而在第二次調(diào)用時(shí),類型參數(shù) string
被傳遞給 identity
函數(shù),所以返回值的類型是 string
。
通過使用泛型,我們可以編寫出更加通用的函數(shù),不限于特定的類型。這樣一來,我們能夠避免代碼的重復(fù)編寫,提高代碼的可復(fù)用性和靈活性。
泛型主要用在四個(gè)場合:函數(shù)、接口、類和別名。
基本使用
泛型使用尖括號(hào) <T>
來表示,并在定義函數(shù)、類或接口時(shí)指定類型參數(shù)。下面是一些基本的使用示例:
// 示例1: 創(chuàng)建一個(gè)泛型函數(shù)
function identity<T>(arg: T): T {
return arg;
}
// 示例2: 使用泛型函數(shù)
let output = identity<string>("Hello");
console.log(output); // 輸出: Hello
// 示例3: 使用類型推斷,自動(dòng)推斷泛型類型
let output2 = identity("Hello");
console.log(output2); // 輸出: Hello
在示例 1 中,函數(shù) identity
使用了泛型類型參數(shù) T
,表示參數(shù)和返回值的類型可以是任何類型。示例 2 和示例 3 展示了如何使用泛型函數(shù)并指定參數(shù)的類型。
。
2. 使用泛型變量:
泛型變量允許我們在函數(shù)或類中使用一種不確定的類型,而在實(shí)際使用時(shí)才確定具體的類型。
舉個(gè)例子,考慮一個(gè)簡單的函數(shù)identity
,它接受一個(gè)參數(shù)并返回相同的值:
function identity<T>(arg: T): T {
return arg;
}
在這個(gè)例子中,我們使用了泛型變量T
,它可以代表任意類型。當(dāng)我們調(diào)用函數(shù)identity
時(shí),編譯器會(huì)根據(jù)傳入的參數(shù)類型自動(dòng)推斷T
的具體類型。
例如:
let result = identity<string>("Hello");
console.log(result); // 輸出:Hello
let value = identity<number>(42);
console.log(value); // 輸出:42
通過使用泛型變量,函數(shù)identity
可以適用于不同類型的參數(shù),提供了更高的靈活性和可重用性。
3. 泛型類型:
泛型類型允許我們創(chuàng)建可以適用于不同類型的變量、函數(shù)或類。
舉個(gè)例子,考慮一個(gè)簡單的數(shù)組反轉(zhuǎn)函數(shù)reverse
:
function reverse<T>(array: T[]): T[] {
return array.reverse();
}
在這個(gè)例子中,我們定義了一個(gè)泛型函數(shù)reverse
,接受一個(gè)數(shù)組參數(shù),并返回反轉(zhuǎn)后的數(shù)組。泛型類型T
用于指定數(shù)組的元素類型。
例如:
let numbers: number[] = [1, 2, 3, 4, 5];
let reversedNumbers = reverse(numbers);
console.log(reversedNumbers); // 輸出:[5, 4, 3, 2, 1]
let strings: string[] = ["apple", "banana", "orange"];
let reversedStrings = reverse(strings);
console.log(reversedStrings); // 輸出:["orange", "banana", "apple"]
通過使用泛型類型,函數(shù)reverse
可以適用于不同類型的數(shù)組,提供了更高的靈活性和可重用性。
4. 泛型類:
泛型類允許我們創(chuàng)建可以適用于多種類型的類。類中的成員可以使用泛型類型進(jìn)行聲明和使用。
舉個(gè)例子,考慮一個(gè)簡單的Box
類,用于存儲(chǔ)任意類型的值:
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
在這個(gè)例子中,我們定義了一個(gè)泛型類Box
,它具有一個(gè)私有成員value
和一個(gè)公共方法getValue
用于獲取值。
例如:
let box1 = new Box<number>(42);
console.log(box1.getValue()); // 輸出:42
let box2 = new Box<string>("Hello");
console.log(box2.getValue()); // 輸出:Hello
過使用泛型參數(shù)<T>
,可以在類的定義中引入類型變量來表示未知的類型。這樣一來,我們可以在類實(shí)例化時(shí)指定具體的類型,從而創(chuàng)建適用于不同類型數(shù)據(jù)的類的實(shí)例。
5. 泛型約束:
泛型約束允許我們限制泛型類型的范圍,使其滿足特定條件
5.1. 確保屬性存在
舉個(gè)例子,假設(shè)我們想編寫一個(gè)函數(shù)getLength
,用于獲取對象的長度。但是并不是所有的對象都有length
屬性,所以我們需要對泛型類型進(jìn)行約束,確保它具有該屬性。
例如:
interface HasLength {
length: number;
}
function getLength<T extends HasLength>(obj: T): number {
return obj.length;
}
在這個(gè)例子中,我們使用泛型約束T extends HasLength
來限制泛型類型T
必須滿足HasLength
接口的要求,即具有length
屬性。
例如:
let str = "Hello";
console.log(getLength(str)); // 輸出:5
let arr = [1, 2, 3, 4, 5];
console.log(getLength(arr)); // 輸出:5
通過使用泛型約束,函數(shù)getLength
可以接受具有length
屬性的對象,并返回其長度。
5.2 檢查對象的 key
1、keyof typescript 中檢測類型的方法,以聯(lián)合類型的方式方返回類型的所有 key
2、搭配泛型約、<T,K extends keyof T >
refshttps://juejin.cn/post/6844904184894980104#heading-0
使用泛型,可以讓我們在編譯前發(fā)現(xiàn)錯(cuò)誤。
6 泛型接口:
泛型接口允許我們定義可以適用于不同類型的接口。
舉個(gè)例子,考慮一個(gè)簡單的Transformer
接口,它定義了一個(gè)將輸入值轉(zhuǎn)換為輸出值的轉(zhuǎn)換器:
interface Transformer<T, U> {
transform(input: T): U;
}
在這個(gè)例子中,我們定義了一個(gè)泛型接口Transformer
,它有兩個(gè)類型參數(shù)T
和U
,用于定義輸入類型和輸出類型。
例如,我們可以實(shí)現(xiàn)一個(gè)字符串到數(shù)字的轉(zhuǎn)換器:
class StringToNumberTransformer implements Transformer<string, number> {
transform(input: string): number {
return parseFloat(input);
}
}
通過定義實(shí)現(xiàn)了Transformer
接口的類,我們可以創(chuàng)建不同類型的轉(zhuǎn)換器。
例如:
let transformer = new StringToNumberTransformer();
let result = transformer.transform("3.14");
console.log(result); // 輸出:3.14
通過使用泛型接口,我們可以定義可重用、可靈活的接口,適用于不同類型的轉(zhuǎn)換操作。
接口搭配泛型,應(yīng)用在 calss 類上
extend people 約束泛型類 在 people 接口范圍內(nèi)
此時(shí)是 泛型變量占位符,在實(shí)例化 class 類是傳遞類型
interface people {
name: string;
age: number;
}
class Popele<T extends people> {
data: T;
constructor(data: T) {
this.data = data;
}
hi() {
return `${this.data.name},,${this.data.age}`;
}
}
let zhagnsan = new Popele<people>({ name: "張三", age: 18 });
總結(jié)
泛型在 TypeScript 中提供了更靈活、可重用的代碼編寫方式。它可以用于定義函數(shù)、類以及接口,讓我們能夠編寫適用于不同類型的代碼。
讀者朋友好呀,我是王天~
嘗試做過很多事情,汽修專業(yè)肄業(yè)生,半路出道的野生程序員、前端講師、新手作者,最終還是喜歡寫代碼、樂于用文字記錄熱衷分享~
如文章有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,期待給于指正,萬分感謝。
如果喜歡或者 有所啟發(fā),歡迎 star,對作者也是一種鼓勵(lì)。
微信:「wangtian3111
」,加我進(jìn)王天唯一的讀者群。文章來源:http://www.zghlxwxcb.cn/news/detail-710817.html
個(gè)人博客:https://itwangtian.com文章來源地址http://www.zghlxwxcb.cn/news/detail-710817.html
到了這里,關(guān)于ts 終于搞懂TS中的泛型啦! | typescript 入門指南 04的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!