return arg;
}
如果我们这个函数要被复用,基本很难,因为类型完全限定死了,那如果把类型放开呢,比如any,那还写啥ts…js不香吗,受这罪…到这里,泛型的作用就体现了,它没有对类型限定死,但是又比any来的严格的多,下面我们具体看
一下;
============================================================
我个人觉得泛型就是在定义的时候,定义了一个虚拟的类型,这个类型需要在被使用的时候才确认,使用的时候是string类型的,那么泛型就是string类型,使用的时候是number类型,那么泛型就是number类型;
而且,我一直认为TS其实就是在玩类型,花式玩类型,很多时候TS的类型注解和JS的代码混在一起,根本就看不懂到底写了个啥…所以任重而道远啊;
泛型简单的来说分为两种,一种叫做:函数泛型,另外一种就是类泛型
顾名思义,使用在函数中的泛型,先直接看个例子
function join(first: T, second: T) {
return ${first}-${second}
;
}
通过<>这个符号来定义一个泛型,<>里面的是代表这个泛型的类型,这个类型可以是任意定义的,并不一定是上例中的T,这个T只是一个代指,具体是什么类型需要等到使用的时候确定,比如下例也是可以的:
function join(first: ABD, second: ABD) {
return ${first}-${second}
;
}
等到使用的时候,只需要指定类型就可以了
// 正确
join(“1”,“2”);
join(1,2);
// 错误
join(1,“2”);
join(“1”,2);
再看一个例子:
function join(first: ABD[], second: Array) {
return […first,…second];
}
我们定义了一个这样的函数,它也是一个函数泛型,但是与之前的例子不同的是,它的两个参数是有类型ABD组成的数组
join(“123”) // 报错
join([“123”]) // 正确
当然,泛型可以写不止一个,再看一个例子,泛型可以写不止一个,多个也是可以的
function join<T,A>(first: T, second: A) {
return ${first}-${second}
;
}
join<string,number>(“1”,123) // 正确
// 甚至,TS是能根据定义的时候做类型推断的
join(“1”,123) // 正确,这么写也没有问题,TS能自己推断出具体类型是什么
可能有的同学看到这里会说,这个泛型确实比一般的类型复杂了点,但是也没上面说的复杂到看不懂啊,好吧,到这里其实只是一些基础知识,来着稍微复杂一点的试炼一下
const getData: (str: T) => string = (str: T): string => {
return ${str}-1
;
};
emmm…,第一反应肯定是有点懵,这是个啥,有点像箭头函数,但是为什么会有两个箭头函数在一起,好吧,我们具体解释一下:
首先我们确定这是一个函数表达式,然后后面应该是跟了一个箭头函数,然后返回的就是这个${str}-1
,当中一部分应该是TS的类型定义,那我换个写法,看看能不能理解:
// 将箭头函数拆解出来
function handleData(str: T): string {
return ${str}-1
;
}
const getData: (str: T) => string = handleData;
这样是不是好理解一点
// 函数名
const getData
// 函数的TS类型
(str: T) => string
// 函数体
function handleData(str: T): string {
return ${str}-1
;
}
// 对应到上面那个简写
// 函数名
const getData
// 函数的TS类型
(str: T) => string
// 函数体
(str: T): string => {
return ${str}-1
;
};
这样是不是能理解了,所以正如我上面所说,当TS的类型写法混入JS语法的时候,很容易让人就看不懂代码了,所以遇到这类代码必须静下心来好好分析,这类代码在一些框架中非常频繁的用到;
泛类型就是在类中使用泛型,老规矩,还是直接看一个例子先:
class Join {
constructor(private data: string[]) {}
getData(index: number): string {
return this.data[index];
}
}
const data = new Join([“123”, “456”]);
data.getData(0);
这个类代码初始化的时候接收一个由字符串组成的数组作为参数,代码本身没有问题,它的问题在于不够灵活,假如我们存储的数组中的类型不再单单是字符串类型,有可能是任何类型,并且返回的,那么,就必须写很长很长的联合类型,比如:
class Join {
constructor(private data: string[]|number[]|boolean[]) {}
getData(index: number): string|number|boolean {
return this.data[index];
}
}
const data = new Join([“123”, “456”]);
data.getData(0);
很明显,这是不合理的,这种就可以用泛型改造,泛型的灵活性确实是TS中的一个亮点,那么泛型这么写,直接看例子吧,先看一个基础用法:
class Join {
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
1171806)]
[外链图片转存中…(img-poPhRfoL-1715721171806)]
[外链图片转存中…(img-mRQpCRbg-1715721171806)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!