TypeScript 關于對【泛型】的定義使用解讀

目錄

    • 概念導讀
    • 泛型函數
    • 多個泛型參數
    • 泛型約束
    • 泛型別名
    • 泛型接口
    • 泛型類
    • 總結:


概念導讀

泛型(Generics)是指在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定類型的一種特性。使用泛型 可以復用類型并且讓類型更加靈活

在這里插入圖片描述
泛型實現類型參數化:

在定義這個函數時, 我不決定這些參數的類型
而是讓調用者以參數的形式告知,我這里的函數參數應該是什么類型
把類型作為參數,放在尖括號中

泛型的基本使用

案例講解:

當我們封裝一個函數的時候,可能由于業務需求的不同,向函數內,傳遞的參數類型也不相同。而TS 的語法規范是,在函數定義的時候就需要為每個待接收的形參以及函數的返回值指定類型,如果在我們調用執行函數之前,就將類型給指定死了的話,這就大大降低了,函數的復用性了。


這時候,就可以使用 泛型,來實現這樣的需求,將函數所需參數的類型,延后到,當我調用函數的時候,可以根據不同的業務需求再指定其參數類型。這樣一來,將大大的提高函數的復用靈活性。


如下案例:

泛型函數

普通函數定義法

function createArray<T>(length: number, value: T): Array<T> {let result: T[] = [];for (let i = 0; i < length; i++) {result[i] = value;}return result;
}createArray(3, 'x'); // ['x', 'x', 'x']

箭頭函數定義法

let append = <T>(val: T, num: number): Array<T> => {const arr: T[] = []for (let index = 0; index < num; index++) {arr.push(val)}return arr;
}
console.log(append<string>("一段字符串", 9));
//['一段字符串', '一段字符串', '一段字符串', '一段字符串', '一段字符串', '一段字符串', '一段字符串', '一段字符串', '一段字符串']
console.log(append<number>(10086, 9));
//[10086, 10086, 10086, 10086, 10086, 10086, 10086, 10086, 10086]

我們在函數名后添加了 < T >,其中 T 用來指代任意輸入的類型(泛型),后面的參數類型,以及函數返回值的類型,都可以 使用 T 泛型來定義站位。
console.log(append< string >("一段字符串", 9)); 在函數調用的時候再為其指定泛型所具體代表的類型,也可以不手動指定,而讓類型推論自動推算出來(推薦手動指定,使其代碼更加清晰明了)


多個泛型參數

定義泛型的時候,可以一次定義多個類型參數,同樣的在調用的時候再為其指定參數類型,多泛型參數多用于元組類型的數據處理

普通函數寫法:

function swap<T, U>(tuple: [T, U]): [U, T] {return [tuple[1], tuple[0]];
}console.log(swap<number, string>([7, 'seven']));

箭頭函數寫法:

let swap = <T, U>(tuple: [T, U]): [U, T] => {return [tuple[1], tuple[0]];
}console.log(swap<string, number>(["字符串", 100]));

泛型約束

由于泛型,表示數據的類型的待定的,由于事先不知道它是哪種類型,所以不能夠隨意操作一個待定數據類型身上的方法屬性,如果傳進來的數據類型沒有這個屬性方法,則就會引起報錯。

如下案例:

function loggingIdentity<T>(arg: T): T {console.log(arg.length);return arg;
}// 報錯:  index.ts(2,19): error TS2339: Property 'length' does not exist on type 'T'.

上例中,泛型 T 不一定包含屬性 length,所以編譯的時候報錯了。

這時候,我們就可以通過接口對泛型進行約束,只允許這個函數傳入那些包含 length 屬性的變量。這就是泛型約束:

interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}

上例中我們使用了 extends 約束了泛型 T 必須符合接口 Lengthwise 的形狀,也就是必須包含 length 屬性。

此時如果調用 loggingIdentity 函數的時候,傳入的 arg 數據類型身上 不包含 length 屬性,那么在編譯階段就會報錯了,這樣一來就大大降低了,會發生在函數體內部的錯誤了

補充

多個類型的參數之間也可以互相約束

function copyFields<T extends U, U>(target: T, source: U): T {for (let id in source) {target[id] = (<T>source)[id];}return target;
}let x = { a: 1, b: 2, c: 3, d: 4 };copyFields(x, { b: 10, d: 20 });

上例中,我們使用了兩個類型參數,其中要求 T 繼承 U,也相當于,U 約束了 T ,這樣就保證了 U 上不會出現 T 中不存在的字段。


泛型別名

在類型別名 type 的后面使用<T>即可聲明一個泛型參數,接口里的其他成員都能使用該參數的類型

type len = {length: number
}let fun = <T extends len>(x: T): number => {return x.length
}
console.log(fun<string>("486789413"));//9

泛型接口

前面提到過, interface 是我們在使用 TypeScript 的時候,用來定義接口的關鍵字。

如:

interface Person {name: string;age: number;
}
const dome: Person = {name: "sunny",age: 18,
};

上面示例的代碼中用聲明接口限制了一個對象,我們也可以通過泛型對我們的接口進行改造

在這里插入圖片描述

這時候我們通過定義泛型的方式,定義 T ,U 兩個占位符,使得我們的接口具備了泛型,更加靈活。但是我們發現 泛型接口和泛型函數不一樣,像上圖中這樣使用,有一個地方報錯了,提示我們需要傳入類型參數,而不能依賴自動的類型推斷,來確實對象屬性的類型,其實這也是可以理解,因為我們對一個對象的限制,主要就是限制對象的屬性類型,如果我們不確定類型,那我們傳入的一切類型都是有效的了。就起不到類型的限制,而前面我們使用泛型函數,雖然沒有顯示聲明類型,但是我們達到了對函數入參和出參進行了統一。

interface Person<T, U> {name: T;age: U;
}
const dome: Person<string, number> = {name: "sunny",age: 18,
};

所以定義泛型接口的時候,正確的寫法應該是 對其傳入了兩個確定的類型。T,U的類型也因此確定了。

泛型接口來約束函數:

interface Person<T> {(value: T): Array<T>
}const printFun: Person<string> = <T>(value: T): Array<T> => {let arr: T[] = [];arr.push(value)return arr;
};
console.log(printFun("233")); //['233']

泛型類

與泛型接口類似,泛型也可以用于類的類型定義中:

class information<T, U>{name: Tage: Uconstructor(name: T, age: U) {this.name = name;this.age = age}
}
let c =  new information<string, number>("張三", 48)

泛型參數的默認類型

在 TypeScript 2.3 以后,我們可以為泛型中的類型參數指定默認類型。當使用泛型時沒有在代碼中直接指定類型參數,從實際值參數中也無法推測出時,這個默認類型就會起作用。

class information<T = string, U = number>{name: Tage: Uconstructor(name: T, age: U) {this.name = name;this.age = age}
}
let c = new information("李四", 25)

總結:

泛型德優勢是什么?

增加類型的復用性和靈活性。

泛型實現的基本方法是什么?

  • 找到不確定類型的部分,為其定義泛型參數
  • 傳入參數時,為泛型指定具體的類型

泛型約束的作用是什么?

既可以,保留泛型的靈活性,又限制了一定的規范。


注明:在正式開發中,泛型的使用場景非常多…


🚵?♂? 博主座右銘:向陽而生,我還在路上!
——————————————————————————————
🚴博主想說:將持續性為社區輸出自己的資源,同時也見證自己的進步!
——————————————————————————————
🤼?♂? 如果都看到這了,博主希望留下你的足跡!【📂收藏!👍點贊!??評論!】
——————————————————————————————

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38026.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38026.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38026.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Oracle切割字符串的方法,SQL語句完成。

Oracle用正則的方式循環切割字符串 需求&#xff1a;有一個這樣子的 Str “‘CNJ-520-180500000001|CNJ-520-181200000001|CNJ-520-190300000001|CNJ-520-190100000001|CNJ-520-181200000002’” &#xff0c;然后我需要拿到每一個單號&#xff0c;每一個單號都要走一遍固定的…

“MongoDB基礎知識【超詳細】

"探索MongoDB的無邊之境&#xff1a;沉浸式數據庫之旅" 歡迎來到MongoDB的精彩世界&#xff01;在這個博客中&#xff0c;我們將帶您進入一個充滿創新和無限潛力的數據庫領域。無論您是開發者、數據工程師還是技術愛好者&#xff0c;MongoDB都將為您帶來一場令人心動…

如何實現安全上網

l 場景描述 政府、軍工、科研等涉密單位或企業往往要比其他組織更早接觸高精尖的技術與產品&#xff0c;相對應的數據保密性要求更高。常規的內外網物理隔離手段&#xff0c;已經滿足不了這些涉密單位的保密需求&#xff0c;發展到現在&#xff0c;需求已經演變成既要保證網絡…

記一次Kafka重復消費解決過程

起因&#xff1a;車聯網項目開發&#xff0c;車輛發生故障需要給三個系統推送消息&#xff0c;故障上報較為頻繁&#xff0c;所以為了不阻塞主流程&#xff0c;采用了使用kafka。消費方負責推送并保存推送記錄&#xff0c;但在一次壓測中發現&#xff0c;實際只發生了10次故障&…

“深入探究JVM內部機制:理解Java虛擬機的工作原理“

標題&#xff1a;深入探究JVM內部機制&#xff1a;理解Java虛擬機的工作原理 摘要&#xff1a;本文將深入探究Java虛擬機&#xff08;JVM&#xff09;的內部機制&#xff0c;幫助讀者理解JVM的工作原理。我們將介紹JVM的組成部分、類加載過程、內存管理和垃圾回收機制&#xf…

帶你了解ChatGPT

目錄 什么是ChatGPT 從ChatGPT角度看聊天機器人的歷史 聊天機器人的早期歷史 ChatGPT的出現 ChatGPT和其他聊天機器人的比較 總結 ChatGPT相比其他聊天機器人的優勢在哪里 1. 自然語言處理能力更強 2. 編程能力高&#xff0c;應用領域廣泛 3. 可以滿足個性化需求 4.…

Golang實現完整聊天室(內附源碼)

項目github地址&#xff1a; 由于我們項目的需要&#xff0c;我就研究了一下關于websocket的相關內容&#xff0c;去實現一個聊天室的功能。 經過幾天的探索&#xff0c;現在使用Gin框架實現了一個完整的聊天室消息實時通知系統。有什么不完善的地方還請大佬指正。 用到的技術…

使用自己的數據利用pytorch搭建全連接神經網絡進行回歸預測

使用自己的數據利用pytorch搭建全連接神經網絡進行回歸預測 1、導入庫2、數據準備3、數據拆分4、數據標準化5、數據轉換6、模型搭建7、模型訓練8、模型預測9、完整代碼 1、導入庫 引入必要的庫&#xff0c;包括PyTorch、Pandas等。 import numpy as np import pandas as pd f…

tp6 RabbitMQ

1、composer 安裝 AMQP 擴展 composer require php-amqplib/php-amqplib 2、RabbitMQ 配置 在 config 目錄下創建 rabbitmq.php 文件 <?php return [host>,port>5672,user>,password>,vhost>,exchange_name > ,queue_name > ,route_key > ,cons…

中國生產了5.07億臺,庫存高達近4億臺?國產手機徹底賣不動了?

統計數據顯示今年上半年中國的手機產量達到5.07億臺&#xff0c;國內市場手機出貨量僅有1.24億臺&#xff0c;都出現了下滑&#xff0c;那么中國手機的產量比銷量多出了3.83億臺&#xff0c;這些手機都成為了庫存&#xff1f; 中國手機市場確實不如早年那么輝煌&#xff0c;201…

【FAQ】安防監控視頻EasyCVR平臺分發的FLV視頻流在VLC中無法播放

眾所周知&#xff0c;TSINGSEE青犀視頻匯聚平臺EasyCVR可支持多協議方式接入&#xff0c;包括主流標準協議國標GB28181、RTSP/Onvif、RTMP等&#xff0c;以及廠家私有協議與SDK接入&#xff0c;包括海康Ehome、海大宇等設備的SDK等。在視頻流的處理與分發上&#xff0c;視頻監控…

P12-Retentive NetWork-RetNet挑戰Transformer

論文地址:https://arxiv.org/abs/2307.08621 目錄 Abstract 一.Introduction 二.Retentive Networks 2.1Retention 2.2Gated Multi-Scale Retention 2.3Overall Architecture of Retention Networks 2.4Relation to and Differences from Previous Methods 三.Experime…

Codeforces Round 892 (Div. 2)(VP)

A //b里放最小值&#xff0c;其他值放c。如果最大值最小值&#xff0c;則無解。 void solve() {int n; cin >> n;vi a(n); liter(x, a) cin >> x; sort(all(a));if (a[0] a[n - 1]){print(-1); return;}vi b, c;for (int i 0; i < sz(a); i){if (a[i] a[0])…

小米基于 Flink 的實時計算資源治理實踐

摘要&#xff1a;本文整理自小米高級軟件工程師張蛟&#xff0c;在 Flink Forward Asia 2022 生產實踐專場的分享。本篇內容主要分為四個部分&#xff1a; 發展現狀與規模框架層治理實踐平臺層治理實踐未來規劃與展望 點擊查看原文視頻 & 演講PPT 一、發展現狀與規模 如上圖…

【03】基礎知識:typescript中的函數

一、typescript 中定義函數的方法 函數聲明法 function test1(): string {return 返回類型為string }function test2(): void {console.log(沒有返回值的方法) }函數表達式/匿名函數 const test3 function(): number {return 1 }二、typescript 中 函數參數寫法 1、typesc…

helm安裝harbor + nerdctl 制作push 鏡像

參考 文章&#xff1a;Helm部署Harbor_helm harbor_風向決定發型丶的博客-CSDN博客 安裝好后使用 nerd containerd對接harbor_containerd 容器 insecure-registries 配置_檸是檸檬的檬的博客-CSDN博客 推送鏡像 Containerd 對接私有鏡像倉庫 Harbor - 知乎 接下來我們來…

麒麟系統相關

創建虛擬機 鏡像下載地址 選擇合適的鏡像&#xff0c;進入引導后注意不要選擇默認的第一條&#xff0c;選擇第二條進入安裝程序。 root密碼修改 使用命令 sudo passwd root 開啟ssh 配置好網絡后發現能ping通&#xff0c;但無法ssh連接&#xff0c;ps -ef | grep ssh 得…

01 qt快速入門

一 qt介紹 1.基本概念 1991年由Qt Company(奇趣)開發的跨平臺C++圖形用戶界面應用程序開發框架,GUI程序和非GUI程序。優點:一套源碼在不同的平臺通過不同的編譯器進行編譯,就可以運行到該平臺上目標機。面向對象的封裝機制來對其接口封裝。 GUI —圖形用戶界面(Graphic…

軟件測試面試題【2023整理版(含答案)】

01、您所熟悉的測試用例設計方法都有哪些&#xff1f;請分別以具體的例子來說明這些方法在測試用例設計工作中的應用。 答&#xff1a;有黑盒和白盒兩種測試種類&#xff0c;黑盒有等價類劃分方法 邊界值分析方法 錯誤推測方法 因果圖方法 判定表驅動分析方法 正交實驗設…

Vue組件之間的傳值匯總

組件之間的傳值 1、父傳子 props 2、父傳子 slot 3、父傳子 不建議用 attrs 4、 子傳父 ref 5、子傳父 emit 6、povide/inject只能在setup的時候用。 7、利用vuex和pinia去實現數據的交互 1、實現代碼App.vue <script setup>import TestProps from ./components/T…