为何使用泛型
我们不仅要创建一致的定义良好的API,同时也要考虑可重用性,可以使用泛型来创建可重用的结构,一个结构可以支持多种类型的数据,泛型实现类、接口、方法的复用性以及对不特定类型的数据的支持
下面定义一个可以返回用户传入值的函数
function fn (value: number): number {
return value
}
上面函数只可以实现传入为数字的情况,无法传入其它类型的值,用any类型可以解决这个问题
function fn (value: any): any {
return value
}
但这样又出现了新的问题,无法确认传入的值和返回的值是同一种类型,any类型可以是任何类型
这个时候,我们使用了一个类型变量 T (规范写法,也可以定义为其它名字)使返回值的类型与传入参数的类型是相同的,它是一种特殊的变量,只用于表示类型而不是值
function fn<T>(value: T): T {
return value
}
我们调用也有两种方法
一种是把包括类型变量在内所有参数传过去,另一种是省略类型变量,编译器自动会判断类型
console.log(fn<number>(123)) // 123
console.log(fn(123)) // 123
定义泛型类
// 普通类
class GetMax {
public arr: number[]
constructor(arr: number[]) {
this.arr = arr
}
getMax(): number {
let max = this.arr[0]
this.arr.forEach(value => {
if (max < value) {
max = value
}
})
return max
}
}
let ex1 = new GetMax([2, 5, 3, 7, 6])
console.log(ex1.getMax()) // 7
// 泛型类
class GetMax1<T> {
public arr: T[]
constructor(arr: T[]) {
this.arr = arr
}
getMax(): T {
let max = this.arr[0]
this.arr.forEach(value => {
if (max < value) {
max = value
}
})
return max
}
}
let ex2 = new GetMax1([2, 5, 3, 7, 6, 9, 12])
console.log(ex2.getMax()) // 12
let ex3 = new GetMax1(['a', 'r', 'F', 'C'])
console.log(ex3.getMax()) // r
定义泛型接口
// 写法一
interface fnRule1 {
<T>(value: T): T
}
var fn1: fnRule1 = function <T>(value: T): T {
return value
}
console.log(fn1<number>(123)) // 123
console.log(fn1<string>('lucky')) // lucky
// 写法二
interface fnRule2<T> {
(value: T):T
}
function getData<T>(value: T): T {
return value
}
var fn2: fnRule2<number> = getData
console.log(fn2(123)) // 123
loading…