TypeScript 泛型

server/2024/9/23 10:48:11/

泛型

介绍

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

泛型之Hello World

下面来创建第一个使用泛型的例子:identity函数。 这个函数会返回任何传入它的值。 你可以把这个函数当成是 echo命令。

不用泛型的话,这个函数可能是下面这样:

function identity(arg: number): number {return arg;
}

或者,我们使用any类型来定义函数:

function identity(arg: any): any {return arg;
}

我们给identity添加了类型变量T。 T帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。 之后我们再次使用了 T当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。 这允许我们跟踪函数里使用的类型的信息。

我们把这个版本的identity函数叫做泛型,因为它可以适用于多个类型。 不同于使用 any,它不会丢失信息,像第一个例子那像保持准确性,传入数值类型并返回数值类型。

我们定义了泛型函数后,可以用两种方法使用。 第一种是,传入所有的参数,包含类型参数:

let output = identity<string>("myString");  // type of output will be 'string'

这里我们明确的指定了Tstring类型,并做为一个参数传给函数,使用了<>括起来而不是()

第二种方法更普遍。利用了类型推论 -- 即编译器会根据传入的参数自动地帮助我们确定T的类型:

let output = identity("myString");  // type of output will be 'string'

注意我们没必要使用尖括号(<>)来明确地传入类型;编译器可以查看myString的值,然后把T设置为它的类型。 类型推论帮助我们保持代码精简和高可读性。如果编译器不能够自动地推断出类型的话,只能像上面那样明确的传入T的类型,在一些复杂的情况下,这是可能出现的。

使用泛型变量

使用泛型创建像identity这样的泛型函数时,编译器要求你在函数体必须正确的使用这个通用的类型。 换句话说,你必须把这些参数当做是任意或所有类型。

看下之前identity例子:

function identity<T>(arg: T): T {return arg;
}

 如果我们想同时打印出arg的长度。 我们很可能会这样做:

function loggingIdentity<T>(arg: T): T {console.log(arg.length);  // Error: T doesn't have .lengthreturn arg;
}

如果这么做,编译器会报错说我们使用了arg.length属性,但是没有地方指明arg具有这个属性。 记住,这些类型变量代表的是任意类型,所以使用这个函数的人可能传入的是个数字,而数字是没有 .length属性的。

现在假设我们想操作T类型的数组而不直接是T。由于我们操作的是数组,所以.length属性是应该存在的。 我们可以像创建其它数组一样创建这个数组:

function loggingIdentity<T>(arg: T[]): T[] {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}

你可以这样理解loggingIdentity的类型:泛型函数loggingIdentity,接收类型参数T和参数arg,它是个元素类型是T的数组,并返回元素类型是T的数组。 如果我们传入数字数组,将返回一个数字数组,因为此时 T的的类型为number。 这可以让我们把泛型变量T当做类型的一部分使用,而不是整个类型,增加了灵活性。

我们也可以这样实现上面的例子:

function loggingIdentity<T>(arg: Array<T>): Array<T> {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}


http://www.ppmy.cn/server/11379.html

相关文章

Expiring 3623 record(s) for 2:xxx ms has passed since batch

Expiring 3623 record(s) for 2:xxx ms has passed since batch 报错大意为&#xff1a;生产发送批次已经创建&#xff0c;但是已经过去120000ms&#xff0c;仍然没有发送&#xff0c;消息过期 (当kafka服务器磁盘空间不足时&#xff0c;也会报此错误。清空磁盘空间&#xff0…

Excel中将单元格格式改成文本后,为何要双击数字才会改变?

将大批量的数值型数字转换成文本型数字&#xff0c;当然不能一个一个的去双击做转换了。以下说说有哪个可以将数值型数字转换成文本型数字的方法。 一、转换方法 方法1.数据分列功能 选中数据后&#xff0c;点击数据选项卡&#xff0c;分列&#xff0c; 分列向导的第一步和…

复现SMO算法:理解SVM、SMO和高斯核【一、了解相关概念】

任务要求 复现带有高斯核的SMO算法。在LIBSVM中找到一个包含超过1000条数据的数据集。在保持超参数一致的情况下&#xff0c;确保自己实现的模型的精度与LIBSVM相比&#xff0c;相差不超过1%。 复现SMO算法&#xff1a;理解SVM、SMO和高斯核 在这篇博客中&#xff0c;我将深…

界面组件DevExpress WinForms v23.2 - 数据展示、UI模板功能全新升级

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

孩子进入叛逆期,最好的教育方式

叛逆期是孩子成长中普遍经历的阶段&#xff0c;这个时期的孩子容易表现出情绪不稳定&#xff0c;抗拒父母的教育和管束。当家长遇到孩子的叛逆期时&#xff0c;又该怎么去做呢&#xff1f;以下几个技巧帮你面对青春期孩子的叛逆问题。 1、当孩子进入叛逆期时&#xff0c;他们可…

K8s: 控制器之StatefulSets对象

StatefulSet 1 ) 概述 Stateful&#xff0c;也就是有状态应用&#xff0c;微服务无状态是一个理想的这么一个环境有些应用是有状态的&#xff0c;比如这个web服务器&#xff0c;它只能运行在一台server上因为它要访问一些持久化的存储比如说 mysql 它就是一个典型的有状态的应…

统一SQL 支持Oracle number/decimal/dec/numeric转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 通过统一SQL&#xff0c;将Oracle中的numb…

数据可视化———Tableau

基本认识&#xff1a; 维度&#xff1a;定性—字符串文本&#xff0c;日期和日期时间等等 度量&#xff1a;定量—连续值&#xff0c;一般属于数值 数据类型&#xff1a; 数值 日期/日期时间 字符串 布尔值 地理值 运算符 算数运算符&#xff1a;加减乘除,%取余&#xff0c;…