为什么要使用泛型

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中的泛型相关推荐

  1. TS学习(八) :TS中的类

    TS中类的书写 以前在js中书写类是这样的,然后我们在加上TS的类型检查你会发现报错了 class User {constructor(name:string,age:number) {this.na ...

  2. TS学习笔记 TS基本类型

    基本类型 类型声明 类型声明是TS非常重要的一个特点 通过类型声明可以指定TS中变量(参数.形参)的类型 指定类型后,当为变量赋值时,TS编辑器会自动检查是否符合类型声明,符合则赋值,否则报错 指定类 ...

  3. React学习(九)-React中发送Ajax请求以及Mock数据

    虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 VX-ID:suibichuanji 点 ...

  4. java中是先学集合还是泛型_Java学习-在集合中使用泛型

    我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int类型数据,另一个处理String类型数据,或者其他自定义类型数据,但是我们没有办法,只能分别写多个方法处理每种数据类型,因为方法的 ...

  5. (转)SpringMVC学习(九)——SpringMVC中实现文件上传

    http://blog.csdn.net/yerenyuan_pku/article/details/72511975 这一篇博文主要来总结下SpringMVC中实现文件上传的步骤.但这里我只讲单个文 ...

  6. React学习(十)-React中编写样式CSS(styled-components)

    虽互不曾谋面,但希望能和你成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 撰文 | 川川 VX-ID:suibichuanji 点 ...

  7. 【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中的泛 ...

  8. 「1.8W字」2020不可多得的 TS 学习指南

    阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...

  9. 硬干货!1.8W字TS 学习指南,我不信你一口气能读完(建议收藏)

    阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从  ...

最新文章

  1. 常用的CSS(收集)
  2. Cloudera Manager 5.3 和 CDH5.3.0 本地(离线)
  3. 图片管理之删除SKU表数据
  4. 日常撕逼:React和Vue到底谁更牛?
  5. 【题解】Grape luogu1156改 dp
  6. Android学习小Demo(13)Android中关于ContentObserver的使用
  7. oracle 消除块竞争(hot blocks)
  8. node.js下mongoose简单操作实例
  9. windows虚拟显示器开发(三)USB显示器
  10. error C2065: “SHELLEXECUTEINFO”: 未声明的标识符
  11. Mock Server基本使用方法
  12. DiscuzX3.n系列域名转向问题的解决
  13. 解决服务器空间满/var/lib/docker/overlay2占用很大,千万慎用 docker system prune -a清理 mongodb等数据库容器及镜像可能被删,找回恢复数据
  14. 输入网络密码来进入共享计算机,Win7系统与其他电脑共享文件提示输入网络密码如何解决...
  15. 企业快速寄件打单教程
  16. c++ 控制台应用程序隐藏dos界面
  17. 第1关:ZooKeeper初体验
  18. Android安卓——入门学习
  19. LPOJ - 5498 「NOIP2010」机器翻译
  20. 如何自己创业开公司 创业流程

热门文章

  1. git commit后回退方法
  2. 绕过限制低价购买和增删低价购买逻辑漏洞
  3. 游戏(2017-12)
  4. 北京交通大学万怀宇:时空交通数据预测方法及应用
  5. 谈SPFA解差分约束最大值最小值的原理...
  6. 小程序图片底部留白问题
  7. 项目实践系列-点击生成自定义设置的二维码
  8. svn commit 提示Aborting commit 失败问题解决办法
  9. 希尔排序的时间复杂度为什么能小于O(n^2)
  10. 高德地图 AMap.Driving