函数的泛型
- 泛型 generic 泛指的类型
- 适用的场景:
- 制定函数的参数为统一的某一类型
- 在调用时才能够确定参数的类型
比如,以下这个函数,我想要对参数进行制约,first的类型必须与second的类型完全一致:
function join(first:number|string,second:number|string){
return `${first}${second}`
}
这时候就需要用到泛型:
image.png
在指定了泛型之后,就制约了两个参数的类型
泛型的特点:
- 调用时才知道是什么类型
join<string>('1','1') //参数只能是字符串
- 可以将参数定义为一个数组类型
function join<T>(first:T[],second:T){
return `${first}${second}`
}
join<string>(['1','2'],'1')
- 函数的泛型可以定义两个
function join<T,P>(first:T[],second:P){
return `${first}${second}`
}
join<string,number>(['1','2'],1)
-
泛型可以通过ts底层的类型推断推断出来
image.png
类中的泛型
在类中,一般需要调用构造函数,而给构造函数传递的类型如果比较难以确定且比较多,
number[]
、string[]
时,可以利用泛型。
class DataManager<T>{
constructor(private data:T[]){
}
getData(index:number):T{
return this.data[index]
}
}
const data = new DataManager([1,2,3])
如果T是一个对象类型,并且需要制定它的一些属性的时候,可以用到interface。
申明了一个泛型T,但我们不知道它是什么类型,
但可以让T继承item这个interface,并且拥有item所拥有的所有属性
interface Item{
name:string
}
class DataManager<T extends Item>{
constructor(private data:T[]){
}
getData(index:number):T{
return this.data[index]
}
}
const data = new DataManager<Item>([{name:'yyc'}])
而这样也约束了类型,这个class只能使用Item作为传递的类型。
同理,如果<T extends number | string>
,那么只能传递number,string
如何使用泛型作为一个具体的类型注解
const func:<T>(params:T) => T = <T>(params:T) => params
//下面的写法更为直观
function hello<T>(params:T){
return params
}
const func:<T>(params:T) => T = hello