初识泛型
泛型的理解:“泛”理解为广泛的,不确定
“型”理解为ts类型
综合理解:不确定的(广泛的)类型
也可以理解为:根据一个值得到另一个值
泛型作用:复用
function getMin<T>(arr:T[]): T{let min = arr[0]arr.forEach((item)=>{if(item<min){min = item}})return min}let min1 = getMin<number>([1,8,3,4,5])let min2 = getMin<number>(["a","bb","ccc","ddd"])console.log(min1,min2); // 打印出:1 "a"
泛型函数
非泛型函数:
// 匿名函数写法let fun1:(str:number)=>number = function(str){return str}// 具名函数写法function fun1(str:number):number{return str}
泛型函数:
// 匿名函数写法let fun2:<T>(str:T)=>T = function(str){return str}// 具名函数写法function fun2<T>(str:T):T{return str}
泛型类型参数可以有多个:
// 匿名函数写法let fun3:<T,U>(first:T,last:U)=>T = function(first,last){return first}// 具名函数写法function fun3<T,U>(first:T,last:U):T{return first}
泛型函数对象字面量写法:
// 匿名函数let fun4: {<T>(key:T):T} = function(key1){return key1}
泛型接口
写法一:不推荐,不明白调用函数时候具体传进去的泛型参数类型
interface Fun{<T>(str:T):T}let fun6:Fun = function(str){return str}
写法二:推荐写法
interface FunIn <T>{(key:T):T}let fun7:FunIn<number> = function(key){return key}
泛型类
语法格式:
class 类名
}
new 类名<类型>
// 泛型类class GetMin<T>{arr:T[] =[];add(key:T){this.arr.push(key)}min(): T{let minKey = this.arr[0]this.arr.forEach((ele)=>{if(minKey > ele){minKey = ele}})return minKey}}let obj = new GetMin<number>()obj.add(1)obj.add(3)obj.add(5)console.log(obj.min()); // 打印: 1let obj2 = new GetMin<string>()obj2.add('a')obj2.add('bb')obj2.add('c')console.log(obj2.min());// 打印:a
泛型约束
泛型的约束可以通过 interface接口 + extends 来实现约束
// 泛型约束interface Len{length:number}function fun<T extends Len>(arg:T){return arg.length}console.log(fun([1,2,3])); // 打印:3console.log(fun('abcd')); // 打印:4console.log(fun(1)); // 报错
上诉代码中,泛型参数T只能接受满足接口Len类型的,有length属性的数据,否则报错
案例
- 例子:框架中axios请求,指定的接口传输指定的参数
```typescript
import axios from ‘axios’
function request
(url:T,obj:API[T]){ return axios.post(url,obj) }
// 作用:预先定义一些类型变量,给后边用 interface API{ ‘/course/buy’:{ id:number }, ‘/course/comment’:{ id:number, message:string } }
request(‘/course/buy’,{id:1}) request(‘/course/comment’,{id:1,message:’贼棒1’}) request(‘/course/comment’,{id:1,message:’贼棒2’})
2. 例子:泛型封装数据库3. keyof 关键字、extends 来限制属性只能从指定接口里获取。```typescriptfunction getProperty<T, K extends keyof T>(o: T, name: K): T[K] {return o[name]}
interface 极客时间课程 {课程名字:string,价格:number[],受众:string,讲师头像?:string|boolean,获取口令():string}let vueCourse: 极客时间课程 = {课程名字:'玩转Vue 3全家桶',价格:[59,129],受众: '前端小老弟',讲师头像:false,获取口令(){return 88}}function getProperty<某种类型, 某种属性 extends keyof 某种类型>(o: 某种类型, name: 某种属性): 某种类型[某种属性] {return o[name]}
