TypeScript---泛型

一.簡介

TypeScript 就引入了“泛型”(generics)。泛型的特點就是帶有“類型參數”(type parameter)。

在日常 TypeScript 編程中,我們經常會遇到這樣的場景:函數的參數類型與返回值類型密切相關。此時,泛型(Generics)就成為了我們編寫靈活、高復用性代碼的重要工具。

來看一個例子來明白泛型的重要性:

function getFristValue(arr: number[]): any {return arr[0]; // 返回數組的第一個數據
}

這段代碼雖然工作正常,但 any 類型 丟失了類型之間的聯系。我們無法知道傳入的是 string[] 還是 number[],返回值類型也就不明確了。

于是,我們使用泛型來表達這種“輸入與輸出類型相關”的關系:

function getFirst<T>(arr: T[]): T {return arr[0];
}

這里的 <T> 就是類型參數,它類似于函數中的變量,調用函數時再決定 T 的具體類型。比如:

function getFirst<T>(arr: T[]): T {return arr[0];
}getFirst<number>([1, 2, 3]); // 返回 number 類型
getFirst(["a", "b", "c"]); // 推斷為 string 類型

二.泛型的寫法

1.function函數

function關鍵字定義的泛型函數,類型參數放在尖括號中,寫在函數名后面。

function fun<T>(a: T): T {return a;
}console.log(fun<number>(1));

那么對于變量形式定義的函數,泛型有下面兩種寫法。

let my_function: <T>(a: T) => T = function <T>(a: T): T {return a;
};let you_function: <typr>(a: typr) => typr = function <typr>(a: typr): typr {return a;
};my_function<number>(10); // 10
you_function<string>("hello"); // "hello"

2.interface接口

interface Box<T> {contents: T;
}let box: Box<number> = { contents: 123 };

3.class類

class Pair<K, V> {constructor(public key: K, public value: V) {}
}const kv = new Pair<string, number>("age", 30);

也可以設置默認值:

class Generic<T = string> {list: T[] = [];add(item: T) {this.list.push(item);}
}const g = new Generic();
g.add("hello"); // 正確
g.add(123);     // 報錯

注意:泛型類不能使用類型參數定義靜態屬性。

class Example<T> {static prop: T; // 報錯
}

4.type類型別名

type Nullable<T> = T | null | undefined;type Container<T> = { value: T };const a: Container<number> = { value: 42 };

三.類型參數的默認值

類型參數可以設置默認值。使用時,如果沒有給出類型參數的值,就會使用默認值。

function getFirst<T = string>(arr: T[]): T {return arr[0];
}

上面示例中,T = string表示類型參數的默認值是string。調用getFirst()時,如果不給出T的值,TypeScript 就認為T等于string

若調用時未顯式提供類型,TypeScript 會自動推斷,但默認值只有在無法推斷時才會生效。

一旦類型參數有默認值,就表示它是可選參數。如果有多個類型參數,可選參數必須在必選參數之后。

function combine<T, U, V = boolean>(a: T, b: U, c: V): [T, U, V] {return [a, b, c];
}const res1 = combine(1, "hello", true);      // [number, string, boolean]
const res2 = combine("a", 2, false);         // [string, number, boolean]
const res3 = combine("x", 3, undefined);     // [string, number, boolean]

四.數組的泛型表示

TypeScript 原生的數據結構,如數組、Map、Set、Promise 都是泛型結構:

《數組》一章提到過,數組類型有一種表示方法是Array<T>。這就是泛型的寫法,Array是 TypeScript 原生的一個類型接口,T是它的類型參數。聲明數組時,需要提供T的值。

let arr: Array<number> = [1, 2, 3];

上面的示例中,Array<number>就是一個泛型,類型參數的值是number,表示該數組的全部成員都是數值。

同樣的,如果數組成員都是字符串,那么類型就寫成Array<string>。事實上,在 TypeScript 內部,數組類型的另一種寫法number[]string[],只是Array<number>Array<string>的簡寫形式。

在 TypeScript 內部,Array是一個泛型接口,類型定義基本是下面的樣子。

interface Array<Type> {length: number;pop(): Type | undefined;push(...items: Type[]): number;// ...
}

其他的 TypeScript 內部數據結構,比如MapSetPromise,其實也是泛型接口,完整的寫法是Map<K, V>Set<T>Promise<T>

TypeScript 默認還提供一個ReadonlyArray<T>接口,表示只讀數組。

function doStuff(values: ReadonlyArray<string>) {values.push("hello!"); // 報錯
}

上面示例中,參數values的類型是ReadonlyArray<string>,表示不能修改這個數組,所以函數體內部新增數組成員就會報錯。因此,如果不希望函數內部改動參數數組,就可以將該參數數組聲明為ReadonlyArray<T>類型。

五.類型參數的約束條件

TypeScript 提供了一種語法,允許在類型參數上面寫明約束條件,如果不滿足條件,編譯時就會報錯。這樣也可以有良好的語義,對類型參數進行說明。

function comp<T extends { length: number }>(a: T, b: T) {if (a.length >= b.length) {return a;}return b;
}

上面示例中,T extends { length: number }就是約束條件,表示類型參數 T 必須滿足{ length: number },否則就會報錯。

comp([1, 2], [1, 2, 3]); // 正確
comp("ab", "abc"); // 正確
comp(1, 2); // 報錯

上面示例中,只要傳入的參數類型不滿足約束條件,就會報錯。

類型參數的約束條件采用下面的形式。

<TypeParameter extends ConstraintType>

上面語法中,TypeParameter表示類型參數,extends是關鍵字,這是必須的,ConstraintType表示類型參數要滿足的條件,即類型參數應該是ConstraintType的子類型。

類型參數可以同時設置約束條件和默認值,前提是默認值必須滿足約束條件。

常見的約束類型

約束類型示例含義說明
{ length: number }T extends { length: number }要求有 length 屬性
stringnumber 等原始類型T extends string只能傳入對應類型
自定義接口或類T extends Person要求 T 是 Person 類型或其子類
聯合類型T extends string | numberT 只能是 stringnumber

六.注意點

1.盡量少用泛型。

泛型雖然靈活,但是會加大代碼的復雜性,使其變得難讀難寫。一般來說,只要使用了泛型,類型聲明通常都不太易讀,容易寫得很復雜。因此,可以不用泛型就不要用。

2.類型參數越少越好。

多一個類型參數,多一道替換步驟,加大復雜性。因此,類型參數越少越好

3.類型參數需要出現兩次。

如果類型參數在定義后只出現一次,那么很可能是不必要的。

4.泛型可以嵌套。

類型參數可以是另一個泛型。

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

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

相關文章

手把手一起使用Miniforge3+mamba平替Anaconda(Win10)

Anaconda 開始對企業收費&#xff0c;目前急需平替Anaconda。這里采用Minforgemamba作為替代&#xff0c;可以避免Anaconda追責&#xff0c;并100%兼容原conda倉庫及使用方式&#xff0c;如果各位小伙伴有更好的平替方式&#xff0c;歡迎分享。 Miniforge3安裝 下載并安裝Min…

【Note】Linux Kernel 主題學習之“完整的嵌入式 Linux 環境、構建工具、編譯工具鏈、CPU 架構”

Linux Kernel 主題學習之“完整的嵌入式 Linux 環境、構建工具、編譯工具鏈、CPU 架構” 一、完整的嵌入式 Linux 環境 一個嵌入式 Linux 系統通常包括以下關鍵組件&#xff08;以 Jetson、樹莓派等 ARM 版 SBC 為例&#xff09;&#xff1a; 交叉編譯工具鏈&#xff08;cros…

Lecture #20:Database Logging

Lecture20目錄&#xff1a;崩潰恢復緩沖池管理策略竊取策略強制策略NO-STEAL-FORCE影子分頁執行恢復缺點日志文件預寫日志&#xff08;WAL&#xff09;執行緩沖池策略日志方案檢查點崩潰恢復 恢復算法是一種確保數據庫ACID的技術&#xff0c;數據庫崩潰后&#xff0c; 所有已經…

Kubernetes高級調度1

目錄 一:初始化容器 Initcontainer 1:Initcontainer 的基本概念 2:示例 1--延遲指定時間后啟動 3:示例 2--使用初始化容器修改內核參數 4:示例 3--等待依賴服務啟動 4:pause容器 二&#xff1a;臨時容器 Ephemeral Containers 1.臨時容器的概念 2.臨時容器的使用 三&a…

服務器機柜與網絡機柜各自的優勢

一、服務器機柜優勢服務器機柜設計有強大的承重結構&#xff0c;能承受大量服務器設備堆疊產生的重量&#xff0c;保障設備安全穩定放置&#xff0c;防止因承重不足導致機柜變形甚至設備損壞&#xff0c;同時&#xff0c;服務器在運行的過程中&#xff0c;會產生大量熱量&#…

AI技術通過提示詞工程(Prompt Engineering)正在深度重塑職場生態和行業格局,這種變革不僅體現在效率提升,更在重構人機協作模式。

AI技術通過提示詞工程&#xff08;Prompt Engineering&#xff09;正在深度重塑職場生態和行業格局&#xff0c;這種變革不僅體現在效率提升&#xff0c;更在重構人機協作模式。以下是關鍵影響維度及未來趨勢分析&#xff1a;一、職場效率革命&#xff08;效率提升300%場景&…

Hugging Face 開源機器人 Reachy Mini 開啟預定

我們最新的開源機器人 Reachy Mini 正式亮相 &#x1f389; 這款富有表現力的開源機器人由 Pollen Robotics 與 Hugging Face 聯合打造&#xff0c;專為人機交互、創意編程和 AI 實驗而設計。它價格親民&#xff0c;體積小巧&#xff0c;卻蘊藏著無限可能。來自全球的各個年齡段…

vue3+node.js+mysql寫接口(二)

目錄 一、產品模塊(products表) 1.1、添加產品(/adminapi/product/add) 1.2、產品列表(/adminapi/product/list) 1.3、編輯產品(/adminapi/product/update) 1.4、首頁產品聯動 二、前臺模塊 2.1、路由配置 2.2、NavBar組件 2.3、新聞搜索 2.4、新聞選項卡 2.5、新聞…

解析LLM層裁剪:Qwen實戰指南

怎么實現對LLM 部分層裁剪輸出結果 Qwen 7b 是28層MLP,28頭 Qwen 14b 是48層MLP,40頭,詞向量維度:5120 模型加載部分 from transformers import AutoTokenizer, AutoModelForCausalLM

【AI大模型】深度學習正則化技術:Batch Normalization (BatchNorm) 詳解

1. 為什么需要 BatchNorm&#xff1f; - 問題的根源&#xff1a;Internal Covariate Shift (ICS)問題描述&#xff1a; 深度神經網絡在訓練過程中&#xff0c;隨著網絡層數的加深&#xff0c;前面層參數的微小更新會導致后面層輸入數據的分布發生顯著變化。這種現象稱為內部協變…

20.緩存問題與解決方案詳解教程

文章目錄1. 緩存基礎概念1.1 什么是緩存1.2 緩存的作用1.3 常見的緩存類型1.4 緩存架構示例2. 緩存雪崩 (Cache Avalanche)2.1 什么是緩存雪崩2.2 緩存雪崩的原因2.3 緩存雪崩的危害2.4 緩存雪崩的解決方案方案1&#xff1a;設置隨機過期時間方案2&#xff1a;緩存集群和主從復…

(滿滿的坑LLAMA3使用申請被拒絕rejected)利用huggingface導入LLAMA3模型

文章目錄前言坑后續前言 大家都知道&#xff0c;使用huggingface導入大模型是使用如下辦法 from transformers import AutoModelForCausalLM, AutoTokenizermodel_name "Qwen/Qwen2.5-7B-Instruct"#要導入的大模型名稱。model AutoModelForCausalLM.from_pretrai…

大規模集群下 Prometheus 監控架構實戰經驗分享

大規模集群下 Prometheus 監控架構實戰經驗分享 1 業務場景描述 在互聯網金融業務發展過程中&#xff0c;我們需要對數千臺主機、上萬容器與微服務實例進行指標監控&#xff0c;并統計歷史數據以支持 SLA 報表、告警與容量規劃。傳統監控系統面臨以下挑戰&#xff1a; 實例動態…

主流消息隊列技術總結和對比

消息隊列&#xff08;Message Queue&#xff0c;簡稱 MQ&#xff09;作為構建分布式互聯網應用的關鍵組件&#xff0c;松耦合的架構設計能顯著提升系統的可用性與可擴展性。在分布式系統中扮演著至關重要的角色&#xff0c;主要承擔著實現異步消息傳遞、應用解耦、流量削峰以及…

數據結構 順序表(3)---順序表的應用

在之間的兩篇文章中&#xff0c;我們著重講了順序表及順序表的實現。今天這篇文章我們將簡單講解關于順序表的三個算法題。這三個題也都屬于力扣上的經典例題。1.例題1:移除元素例題來源(力扣) : https://leetcode.cn/problems/remove-element/description/這是一道數組操作算法…

逆向入門(9)匯編篇-bound指令的學習

看程序的時候碰到這么一行沒見過的代碼&#xff0c;簡單記錄一下 00427AC8 |. 6215 3C7B4200 |bound edx,qword ptr ds:[0x427B3C]這里是用到了bound指令&#xff0c;這是 x86 匯編中的指令&#xff0c;用于檢查數組索引是否在有效范圍內。 指令解析 bound edx, qword ptr ds…

【web應用】若依框架中,使用Echarts導出報表為PDF文件

文章目錄前言一、Echarts準備工作1、查看是否安裝了Echarts2、Echarts導入script 中3、使用Echarts創建圖表二、報表制作打印html2canvas和jsPDF準備工作1、安裝html2canvas和jsPDF依賴包2、html2canvas和jsPDF引用到script中3、制作并打印報表三、導出結果前言 若依框架前端中…

優選算法 --(雙指針算法 1~8)

引言&#xff1a;此專欄為記錄算法學習&#xff0c;本專題作為算法學習的第一部分&#xff0c;優選算法專題共計100題&#xff0c;分為不同小模塊進行&#xff0c;算法學習需堅持積累&#xff0c;時代不會辜負長期主義者&#xff0c;僅以此句&#xff0c;與君共勉。 講解算法分…

XRDMatch代碼復現與分析報告

XRDMatch代碼復現與分析報告 1. 項目概述 XRDMatch是一個用于X射線衍射(XRD)數據匹配和分析的開源工具,由zhengwan-chem開發并托管在GitHub上。本項目旨在復現XRDMatch的核心功能,并對其實現進行詳細分析。 X射線衍射是材料科學中用于確定晶體結構的重要技術,通過分析衍射…

SpringAI×Ollama:Java生態無縫集成本地大模型實踐指南

摘要 隨著大語言模型(LLM)的普及,數據隱私和技術棧統一性成為企業級AI應用的核心挑戰。本文系統闡述如何通過SpringAI框架與Ollama本地化模型引擎的結合,構建安全高效的生成式AI應用。通過實戰案例解析配置優化、流式響應、工具調用等關鍵技術,為Java開發者提供零Python依…