为什么要说泛型呢?最新看源码,刷帖的时候,看见一片哀嚎。特别是在工具库代码内部,成片成片的
T
,U
等泛型,像雪花一样飘过来。都叫一个名称,整个代码里面一打岔,就不知道在看撒了。 em...老年人有记小笔记,断点的习惯,还能好一些。
为什么会有泛型
当我们写ts代码的时候,需要标注各种类型的数据。因为代码是一些逻辑内容的书面化的体现,内部是有一些规律的。CV
大法在这种情况下是可以用的。
但是,当我们需要更改的时候。那就比较头疼了。当然你也可以提出这些类型,做对应的公共标注。
我们经常说,抽象化编程。当我们在公共的类型,总结基础的规律规则。
你会发现,它其中的一部分就是泛型。
被我们用来表示一类大概类型的类型。
ts 的泛型是什么
1.定义
它是一个高级类型。所谓高级类型是对比基础类型而言。 语义上它是一个广泛的类型。在定义之初泛指某一类的类型,尚未有实际的意义。 作为自定义的类型时,可以复用。
2.语法
以下使用泛型函数举🌰,示范语法
// 定义一个入参出参为同一个类型的函数
function demoFuc<T>(arg: T):T{
return arg;
}
// 实际使用的时
const concatStr = demoFuc<string>('hi') // 返回:hi
3.常用的泛型标识
我们看到代码中的泛型,其实常用的泛型为一些固定的类型,以下举🌰一些常用的
T
任意类型K
对象中的键V
对象中的值E
表示枚举类型A
表示数组类型中的元素类型R
表示返回值类型C
表示类的类型F
表示函数类型
细心的小伙伴,应该发现规律了,大写的字母,代表了某些单词的首字母💡
泛型的基础使用场景
函数
泛型函数,在语法举例中已经说过了
接口的定义
inteface demoObj<T> {
[key: string]: T;
}
// 定义
const aObj: demoObj<string> = {a: '1', b: '2'};
const aArr: demoObj<{a: string}> = {b: {a: '1'}};
成片的泛型场景
成片的泛型大军准备袭来,请准备接招
约束
缩小泛型可定义使用的范围,让泛型更加准确
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// 表示:返回值只能为 obj 对象内存在的 key
类型别名
类型一般用于多类型指定。举🌰
比如:现在需要有多个tooltip按钮,按钮的tool为按钮text内容
interface IButtonsProps<T> {
data: T[] | T
}
type typeProps = {
name: string;
text: string;
tip: string;
}
const Btns = (props: IButtonsProps<typeProps>) => {
const { data } = props;
const isSingleBtn = useMemo({
return !Array.isArray(data) && data.text
}, [data])
return (
isSingleBtn
?
<btn tip={data.tip}>{data.text}</btn>
:
data.map(
(item: item) =>
(<btn key={item.name} tip={item.tip}>{item.text}</btn>))
)
}
默认值
可以为常用的类型,赋值默认类型。
请脑补正常赋值默认值的方式,方式相同。
不赘述。
其他
正常使用TS编码过程中,个人建议还是写人能看得懂的代码,合适的时候加上必要的注释。 除却之上的使用方式,还有根据不同条件,逻辑推断出来的泛型。
我们需要在合适的时候,减少冗余代码的编写,保持简洁,可读性。