泛型
在定义函数、接口、类的时候不能预先确定要使用的数据类型,而是在使用函数接口类的时候才能确定数据类型
(() => {
// 需求:定义一个函数,传入两个参数,第一个参数是数据,第二个参数是数量,函数的作用:根据数量产生对应个数的数据,存放在一个数组中
// 传入任意数据,而且有错误提示信息
function getArr4<T>(value: T, count: number): T[] {
// 根据数据和数量产生一个数组
// const arr: string[] = [];
const arr: Array<T> = []
for (let i = 0; i < count; i++) {
arr.push(value)
}
return arr
}
const arr1 = getArr4<string>('a', 2)
const arr2 = getArr4<number>(23, 2)
console.log(arr1[0].split(''));
console.log(arr2[0].toFixed(3));
})()
多个泛型参数的函数
多个泛型参数的函数:函数中有多个泛型的参数
(() => {
function getMsg<K, V>(value1: K, value2: V): [K, V] {
return [value1, value2];
}
const arr1 = getMsg<string, number>('jack', 100.23)
console.log(arr1[0].split(''), arr1[1].toFixed(1));
})()
泛型接口
// 泛型接口:在定义接口时,为接口中的属性或方法定义泛型类型,在使用接口时,再指定具体的泛型类型
(() => {
// 需求:定义一个类,用来存储用户的相关信息
// 通过一个类的实例对象调用相关的方法可以添加多个用户信息对象,调用getUserId方法可以根据id获取某个指定的用户信息对象
// 定义一个泛型接口
interface IBaseCRUD<T> {
data: Array<T>
add: (t: T) => T
getUserId: (id: number) => T
}
// 定义一个用户信息的类
class User {
id?: number
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
class UserCRUD implements IBaseCRUD<User> {
data: Array<User> = []
// 方法用来存储用户信息对象的
add(user: User): User {
user.id = Date.now() + Math.random()
this.data.push(user)
return user
}
// 根据id查询指定的用户信息对象
getUserId(id: number): User {
return this.data.find(user => user.id === id)
}
}
// 实例化添加用户信息对象的类UserCRUD
const userCRUD: UserCRUD = new UserCRUD()
userCRUD.add(new User('jack', 20))
userCRUD.add(new User('jack1', 21))
userCRUD.add(new User('jack2', 22))
const { id } = userCRUD.add(new User('jack3', 23))
console.log(userCRUD.data);
// 根据id查询用户数据
const user = userCRUD.getUserId(id)
console.log(user);
})()
泛型类
(() => {
// 定义一个类,类中的属性值的类型是不确定的,方法中的参数及返回值的类型也是不确定的
// 定义一个泛型类
class GenericNumber<T>{
// 默认的属性的值的类型是泛型类型
defaultValue: T | undefined
add: ((x: T, y: T) => T) | undefined
}
// 在实例化对象的时候,再确定泛型的类型
const g1: GenericNumber<number> = new GenericNumber<number>();
// 设置属性值
g1.defaultValue = 100
// 相加的方法
g1.add = function (x, y) {
return x + y
}
console.log(g1.add(10, 20));
const g2: GenericNumber<string> = new GenericNumber<string>();
// 设置属性值
g2.defaultValue = '100'
// 相加的方法
g2.add = function (x, y) {
return x + y
}
console.log(g2.add('12', '34'));
})()
泛型约束
// 如果我们直接对一个泛型参数取length属性,会报错,因为这个泛型根本不知道他有这个属性
(() => {
// 定义一个接口,用来约束将来的的某个类型中必须要有的length这个属性
interface ILength {
// 接口中有一个属性length
length: number
}
function getLength<T extends ILength>(x: T): number {
return x.length
}
console.log(getLength<string>('ehoehoh hdhfodhof jodjfo '))
// console.log(getLength<number>(123)) // 因为数字没有length属性
})()