TS学习(九) :TS中的泛型
为什么要使用泛型
function fn(arr, n: number) {return arr
}
在上面函数中第一个参数是个数组,第二个参数我们可以确定是个number类型的数字,但是第一个参数我们无法断定
它是number[]的数组,还是string[]的数组,它可以是任何类型的数组,既然是任何类型那我们是不是可以写成any[]类型
function fn(arr: any[], n: number):any[] {return arr
}
函数的参数,返回值都是any[]类型的数组,当我们给函数传入一个string[]类型的数组,
const newArr = fn(['1', '2', '3', '4', '5', '6'], 3)
按理来说,在函数里面因该能识别出函数的参数类型,函数的返回值类型都是string[]类型,结果显而易见无法识别,
所以这里使用any类型是不行的,所以这个时候我们就得使用泛型来解决这个问题。总的来说,有时,书写某个函数时,会丢失一些类型信息(多个位置的类型应该保持一致或有关联的信息)
什么是泛型
泛型是指附属于函数、类、接口、类型别名之上的类型,当某个函数的参数,返回值和内部使用时的类型无法确定的情况下,就可以使用泛型来进行约束
如何使用或书写泛型
在函数名之后写上fn<泛型名>
,通常泛型名使用大写的T,当然你可以随意命名,在调用的时候函数名字后面加上fn<泛型类型>
function fn<T>(arr:any[], n: number):any[] {}
fn<number>(['1','2','3'],2)
泛型类型“T”就像一个参数,可供传递,如我们在调用函数时在尖括号中传入,则这个T(泛型)的类型就是number,
这样我们就可以any类型都换成泛型就可以了,这样就当泛型参数传入number类型时,函数的返回值就是number类型的数组
function fn<T>(arr:T[], n: number) :T[]{const newArr: T[] = [];return newArr
}
const newArr = fn<number>([1, 2, 3, 4, 5, 6], 3)
这里 T类型就是number,TS就会识别类型,当然你也可以不传入泛型类型,如下
function fn<T>(arr:T[], n: number) :T[]{if (n >= arr.length) {return arr}const newArr: T[] = [];for (let i = 0; i < n; i++) {newArr.push(arr[i])}return newArr
}
const newArr = fn([1, 2, 3, 4, 5, 6], 3)
这时TS会自动识别[1, 2, 3, 4, 5, 6]函数第一个参数你传入的是一个number[]类型的数组,fn<T>(arr:T[], n: number) :T[]{
从而推导出arr:T[]
中的T泛型是number类型,这样其他几个T泛型也都是number,这样最终的返回结果newArr也是number[]类型的数组
说到这里不知道大家有没有疑问,当如果我不传递T泛型参数时,我的数组是长这样的[1, 2, '4', 5],那它返回的是什么类型?
是any吗?还是说还是一个数组,只不过是里面既有number又有string类型的数组,当然是第二种的只不过这个时候表示的是(string | number)[]的写法
function fn<T>(arr:T[], n: number) :T[]{if (n >= arr.length) {return arr}const newArr: T[] = [];for (let i = 0; i < n; i++) {newArr.push(arr[i])}return newArr
}const newArr = fn([1, 2, '4', 5, 5, 6], 3)
当然这种是在你不传递Tf泛型参数的情况下才能这样的,如果又泛型参数,就只能规规矩矩的进行了
总结在函数中使用泛型
泛型相当于是一个类型变量,在定义时,无法预先知道具体的类型,可以使用该变量来代替,只有到调用时,才能确定它的类型
很多时候,TS会只能的根据传递参数,推导泛型的具体类型,如果无法推导,并且又没有传递具体的类型,则会返回空对象的类型
当然泛型也可以设置默认值,当没有传递时就使用默认值,就像js中函数中的参数一样设置默认值
在类型别名、接口、类型中使用泛型
直接在名称后面写上<泛型名称>
- 类型别名
例子: 回调函数:判断数组中的某一项是否满足条件
type callback= (n:number,i:number)=>boolean;
该类型只能传number类型的数组,这就有弊端,我不一定数组就是number类型的,不确定类型,
type callback<T>= (n:T,i:number)=>boolean;
这个时候就可以使用泛型了,只要传入类型泛型类型T,n的类型也是T,这样就可以根据传入的类型就可以了
- 接口:这个和类型别名类似 例子如下
interface callback<T>{(n:T,i:number):boolean;}
//类似js数组中的filter方法
function filter<T>(arr: T[], callback: callback<T>): T[] {const newArr: T[] = [];arr.forEach((n,i)=>{if(callback(n,i)){newArr.push(n);}})return newArr
}
- 类
先看例子,这样写handle1和handle2的泛型没有任何联系,在调用的时候传什么就是什么
class arrayHelper{handle1<T>(arr:T[]):T[]{}handle2<T>(arr:T[]):T[]{}
}
这样写就没啥意思,我们想能只要传一个就代表所有,如下
class arrayHelper<T>{constructor(private arr:T[]) {}handle1(n:number){//使用arr的时候就用this.arr就行了let newArr:T[]=this.arr}handle2(){let newArr:T[]=this.arr}
}
这样就不用在每次调用函数的时候去传入泛型,而是在创建类型时去传入,这样就可以整个类都是该类型
TS学习(九) :TS中的泛型相关推荐
- TS学习(八) :TS中的类
TS中类的书写 以前在js中书写类是这样的,然后我们在加上TS的类型检查你会发现报错了 class User {constructor(name:string,age:number) {this.na ...
- TS学习笔记 TS基本类型
基本类型 类型声明 类型声明是TS非常重要的一个特点 通过类型声明可以指定TS中变量(参数.形参)的类型 指定类型后,当为变量赋值时,TS编辑器会自动检查是否符合类型声明,符合则赋值,否则报错 指定类 ...
- React学习(九)-React中发送Ajax请求以及Mock数据
虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 VX-ID:suibichuanji 点 ...
- java中是先学集合还是泛型_Java学习-在集合中使用泛型
我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int类型数据,另一个处理String类型数据,或者其他自定义类型数据,但是我们没有办法,只能分别写多个方法处理每种数据类型,因为方法的 ...
- (转)SpringMVC学习(九)——SpringMVC中实现文件上传
http://blog.csdn.net/yerenyuan_pku/article/details/72511975 这一篇博文主要来总结下SpringMVC中实现文件上传的步骤.但这里我只讲单个文 ...
- React学习(十)-React中编写样式CSS(styled-components)
虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 VX-ID:suibichuanji 点 ...
- 【TS学习和在react中的简单应用】
TS学习和在react中的简单应用 1. ts基础 1.1 ts基本类型 1.2 数组 1.3 对象 1.4 函数 1.5 class类 1.6 枚举enum 1.7 typeof 1.8 TS中的泛 ...
- 「1.8W字」2020不可多得的 TS 学习指南
阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...
- 硬干货!1.8W字TS 学习指南,我不信你一口气能读完(建议收藏)
阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...
最新文章
- 常用的CSS(收集)
- Cloudera Manager 5.3 和 CDH5.3.0 本地(离线)
- 图片管理之删除SKU表数据
- 日常撕逼:React和Vue到底谁更牛?
- 【题解】Grape luogu1156改 dp
- Android学习小Demo(13)Android中关于ContentObserver的使用
- oracle 消除块竞争(hot blocks)
- node.js下mongoose简单操作实例
- windows虚拟显示器开发(三)USB显示器
- error C2065: “SHELLEXECUTEINFO”: 未声明的标识符
- Mock Server基本使用方法
- DiscuzX3.n系列域名转向问题的解决
- 解决服务器空间满/var/lib/docker/overlay2占用很大,千万慎用 docker system prune -a清理 mongodb等数据库容器及镜像可能被删,找回恢复数据
- 输入网络密码来进入共享计算机,Win7系统与其他电脑共享文件提示输入网络密码如何解决...
- 企业快速寄件打单教程
- c++ 控制台应用程序隐藏dos界面
- 第1关:ZooKeeper初体验
- Android安卓——入门学习
- LPOJ - 5498 「NOIP2010」机器翻译
- 如何自己创业开公司 创业流程