泛型
书写某个函数时,会丢失一些类型信息(多个位置的类型应该保持一致或有关联的信息)
- 泛型:指附属于函数,类,接口别名之上的类型
- 在函数中使用泛型,在函数名之后写上
<泛型名称> - 泛型相当于一个类型变量,在定义时,无法预知具体类型,可以用该变量来代替;只有到调用时,才能确定它的类型
- 很多时候,ts会智能的根据传递的参数,推导出泛型的具体类型;如果无法完成推导,并且又没有传递具体类型,默认为空对象
// 函数使用泛型
function take<T>(arr: T[], n:number): T[]{
if(n >= arr.length) {
return arr
}
const newArr: T[] = []
for(let i = 0; i < n; i++){
newArr.push(arr[i])
}
return newArr
}
take<number>([1,2,3], 2 )
// 类型别名
type callback<T> = (n: T, i: number) => boolean
function filter<T>(arr: T[], callback: callback<T>): T[]{
const newArr: T[] = []
arr.forEach((n, i) => {
if(callback(n,i)) {
newArr.push(n)
}
})
return newArr
}
const arr = [1,2,3,4,5]
console.log(filter(arr, n => n % 2 !== 0 ))
泛型约束
- 用于限制泛型的取值
// 将某个对象的name属性的每个单词的首字母大小,然后将该对象返回
interface hasNameProperty {
name: string
}
// 使用extends使得T具有接口hasNameProperty的属性,不约束的话,obj.name会报错,因为函数接收的参数不知道识哪一种类型
function nameToUpperCase<T extends hasNameProperty>(obj: T): T{
obj.name = obj.name.split(" ")
.map(str => str[0].toUpperCase + str.substr(1))
.join(" ")
return obj
}
const user = {
name: "zero",
age: 18
}
const newUser = nameToUpperCase(user)
多泛型
- 依赖多种类型
// 将两个数组进行混合[1,2,3] ['a', 'b', 'c'] [1,'a',2,'b',3,'c']
function mixinArray<T, K>(arr1: T[], arr2: K[]): (T | K)[] {
if (arr1.length !== arr2.length) {
throw new Error("两个数组长度不相等")
}
let result: (T | K)[] = []
for (let i = 0; i < arr1.length, i++){
result.push(arr1[i])
result.push(arr2[i])
}
return result;
}
mixinArray([1,2,3], ['a','b','c'])