泛型

126 阅读1分钟

泛型接口

函数接口

写法一: 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属性