泛型接口
函数接口
写法一:
interface fn{ <T>(arg1:T, arg2:T):T }
let normalFunc:fn
直接类型赋值,不用指定具体泛型类型。
写法二:(把T放到外面)
interface fn<T>{ (arg1:T, arg2:T):T }
let normalFunc:fn<string>
这里必须指定类型,否则会报错。
泛型类
class People{
add:<T>(arg1:T, arg2:T)=>T;
}
const adder = new Adder()
adder.add= function add<T>(arg1:T, arg2:T){
return arg1+arg2
}
// 这样写会报错,因为函数里的加法`arg1+arg2`,number或string类型没问题,如果T是对象就不能用加法了。
// 解决这个问题有两种方法,一是在类上加T,二是在使用add方法时指定类型
// 方法一:
class People<T>{
add:<T>(arg1:T, arg2:T)=>T;
}
const adder = new Adder<number>() // 这里指定number类型
adder.add= function add(arg1, arg2){ // 这里就不需要T了,new的时候已经指定好了。
return arg1+arg2
}
adder.add(1,2)
//方法二:
class People{
add:<T>(arg1:T, arg2:T)=>T;
}
const adder = new Adder()
adder.add= function add<T>(arg1:T, arg2:T){
return arg1+arg2
}
adder.add<number>(1,2)
泛型约束
fuction animol<T>(arg:T):T{
console.log(arg.length)
return arg
}
// 会报错,因为arg不一定有length属性,T是未定的
使用extends
示例1
interface Len{
length:number
}
fuction animol<T extends Len>(arg:T):T{
console.log(arg.length)
return arg
}
// 调用
animol<string>('字符串')// 正确
animol<boolean>(true) // 报错,布尔没有length属性
示例2(keyof)
function People<T, K>(obj:T, key:K){
return obj[key]
}
// 报错,因为obj类型未确定,不一定是对象,不一定有key属性
// 解决
function people<T, K extends keyof T>(obj:T, key:K){
return obj[key]
}
// keyof T得到T的属性名的联合类型,然后让K继承这个联合类型
const peopleIns = {name:'xxx',age:18}
people(peopleIns, 'name') // 正确
people(peopleIns, 'names') // 报错,没有names属性