泛型
// 泛型:在定义函数、接口、类的时候不能预先确定要使用的数据类型
(()=>{
// 需求:定义一个函数,传入两个参数,第一个参数是数据,第二个参数是数量
// 根据数量产生对应个数的数据,存放在一个数组中
// function getArr(val:number,count:number):number[]{
// // 根据数据和数量产生了一个数组
// const arr:number[] =[]
// for(let i = 0;i<count;i++){
// arr.push(val)
// }
// return arr
// }
// function getArr2(val:string,count:number):string[]{
// // 根据数据和数量产生了一个数组
// const arr:string[] =[]
// for(let i = 0;i<count;i++){
// arr.push(val)
// }
// return arr
// }
// const arr1 = getArr(100.123,3)
// console.log(arr1);
// const arr2 = getArr2('abc',3)
// console.log(arr2);
// // 可以传入任意类型的数据,返回来的是存储这个任意类型数据的数组
// function getArr3(val:any,count:number):string[]{
// // 根据数据和数量产生了一个数组
// const arr:string[] =[]
// for(let i = 0;i<count;i++){
// arr.push(val)
// }
// return arr
// }
// const arr3 = getArr3(100.123,3)
// const arr4 = getArr3('123',3)
// console.log(arr3);
// console.log(arr4);
// // arr中存储的数字类型的数据
// // arr2中存储的数字类型的数据
// console.log(arr1[0].toFixed(2)); // toFixed没有任何智能提示
// console.log(arr2[0].split(';')); // split没有任何智能提示
function getArr4<T>(val:T,count:number):T[]{
// 根据数据和数量产生了一个数组
// const arr:Array<T> =[] 效果一样
const arr:T[] =[]
for(let i = 0;i<count;i++){
arr.push(val)
}
return arr
}
const arr1 = getArr4<number>(200,123)
const arr2 = getArr4<string>('123',123)
console.log(arr1[0].toFixed(2));
console.log(arr2[0].split(';'));
})()
多泛型参数
// 函数中
(()=>{
function getArr<K,V>(val1:K,val2:V):[K,V]{
// 根据数据和数量产生了一个数组
// const arr:Array<T> =[] 效果一样
return [val1,val2]
}
const arr1 = getArr<number,string>(200,'123')
console.log(arr1[0].toFixed(2));
console.log(arr1[1].split(''));
})()
泛型接口
// 泛型接口,在定义接口时,为接口中的属性或方法定义泛型类型,在使用时指定具体泛型类型
(()=>{
// 需求:定义一个类,原来存储用户的相关信息(id,名字,年龄),通过一个类的实例对象
// 通过一个类的实例对象调用add的方法可以添加多个用户信息对象,调用getUserId方法可以根据用户id获取某个指定的用户信息对象
// 定义一个泛型接口
interface IBaseCRUD<T>{
data:Array<T>
add:(t:T)=>T
getUserId:(id:number)=>T
}
// 定义一个用户信息的类
class User{
id?:number // 用户的id
name:string // 用户的姓名
age:number // 用户的年龄
constructor(name:string,age:number){
this.name = name
this.age = age
}
}
// 定义一个类,可以针对用户的信息对象进行增加、查询的操作
class UserCRUD implements IBaseCRUD<User>{
// 用来保存多个user类型的用户信息对象
data:User[] = []
// 存储用户信息对象
add(user:User):User{
user.id = Date.now()
// 把用户信息对象添加到data数组中
this.data.push(user)
return user
}
// 根据id查询指定的用户信息
getUserId(id:number):User{
console.log('id',id);
return this.data.find(user=>user.id === id)
}
}
// 实例化添加用户信息对象的类
const userCRUD:UserCRUD = new UserCRUD()
console.log(userCRUD.add(new User('黄',20)));
console.log(userCRUD.add(new User('梁',18)));
console.log(userCRUD.data);
const {id} = userCRUD.add(new User('a',19));
console.log(id);
console.log(userCRUD.getUserId(id));
})()
泛型类
(()=>{
// 定义一个类,类中的属性值的类型是不确定,方法中的参数及返回值的类型也是不确定
// 定义一个泛型类
class GenericNumber<T>{
// 默认的属性的值的类型是泛型
defaultValue:T
add:(x:T,Y:T) => T
}
const g1:GenericNumber<number> = new GenericNumber<number>()
// 设置属性值
g1.defaultValue = 100
// 添加方法
g1.add = function(x,y){
return x+y
}
const g2:GenericNumber<string> = new GenericNumber<string>()
// 设置属性值
g2.defaultValue = '1'
// 添加方法
g2.add = function(x,y){
return x+y
}
console.log(g2.add('1','2'));
})()
泛型约束
// 如果我们直接对一个泛型参数取length属性,会报错,因为这个泛型根本不知道长度
(()=>{
// 定义一个接口,用来约束将来某个类型中必须要有length这个属性
interface ILength{
length:number
}
function getLength<T extends ILength>(x:T):number{
return x.length
}
console.log(getLength<any[]>(['3','2']));
console.log(getLength<string>('1'));
})()