一.简介

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依…