# 泛型
泛型是指一种在定义接口、类或函数的时候,不预先指定具体的类型,等到使用的时候再指定具体类型的特性
# 举个🌰
function initArr(val: any, count: number): any[] {
const arr: any[] = []
for (let i = 0; i < count; i++) {
arr.push(val)
}
return arr
}
const arr1 = initArr(123.111, 3)
const arr2 = initArr('Ethan', 3)
console.log(arr1[0].toFixed(2), arr2[0].split(''))
// 元素类型为any的话,操作元素的时候没有智能提示(对应元素类型的方法名或错误提示)
# 泛型函数
function initArr2<T>(val: T, count: number): T[] {
// const arr: T[] = []
const arr: Array<T> = []
for (let i = 0; i < count; i++) {
arr.push(val)
}
return arr
}
const arr3 = initArr2<number>(111, 3)
console.log(arr3[0].toFixed(2)) // 有提示信息
// console.log(arr3[0].split(2)) // 报错:类型“number”上不存在属性“split”
多个泛型参数
function foo<K, V>(key: K, val: V): [K, V] {
return [key, val]
}
console.log(foo(1, '2')) // [1, '2']
# 泛型接口
定义接口时,接口中的属性/方法定义为泛型类型
使用接口时,再指定具体的数据类型
interface IbaseCRUD<T> {
data: T[]
add: (t: T) => void
getById: (id: number) => T
}
class User {
id?: number // id主键自增
name: string // 姓名
age: number // 年龄
constructor(name, age) {
this.name = name
this.age = age
}
}
class UserCRUD implements IbaseCRUD<User> {
data: User[] = []
add(user: User): void {
user = { ...user, id: Date.now() }
this.data.push(user)
console.log('add_user', user)
}
getById(id: number): User {
return this.data.find(item => item.id === id)
}
}
const userRUD = new UserCRUD()
userRUD.add(new User('Ethan', 30))
userRUD.add({ name: 'Linna', age: 30 }) // 符合class User
// userRUD.add({ name: 'Ryan', age: 6, sex: 'Male' }) // 对象文字可以只指定已知属性,并且“sex”不在类型“User”中
console.log(userRUD.data)
# 泛型类
定义类时,类中的属性/方法定义为泛型类型
创建类实例时,再指定具体的数据类型
class GNumber<T> {
zero: T
add: (x: T, y: T) => T
}
let gnum = new GNumber<number>()
gnum.zero = 0
gnum.add = function (x, y) {
return x + y
}
let gstr = new GNumber<string>()
gstr.zero = 'abc'
gstr.add = function (x, y) {
return x + y
}
console.log(gnum.add(gnum.zero, 66)) // 66
console.log(gstr.add(gstr.zero, 'def')) // abcdef
# 泛型约束
当没有泛型约束时,会导致不清楚泛型拥有哪些属性可操作
function fnc<T>(x: T): void {
// console.log(x.length) // 报错:类型“T”上不存在属性“length”。
}
实现泛型约束
interface Length {
length: number
}
// 指定泛型约束
function fnc2<T extends Length>(x: T): void {
console.log(x.length)
}
// 必须传入符合约束类型的值
fnc2('abc')
// fnc2(12375) // 报错:类型“number”的参数不能赋给类型“Length”的参数