TypeScrip泛型

48 阅读2分钟

在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。

泛型基础

function getArr <T> (value: T, count: number) {
    const arr: Array<T> = []
     for (let index = 0; index < count; index++) {
         arr.push(value)
     }
     return arr
}

const arr = getArr<number>(200.12345, 5)
const arr2 = getArr<string>('abcdefg', 5)

多个泛型参数的函数

function getMultiType <K, V> (a: K, b: V): [K, V] {
   return [a, b] 
}

const result = getMultiType <string, number> ("hello", 66.66666)   //['hello', 66.66666]

泛型接口

  • 在定义接口时, 为接口中的属性或方法定义泛型类型
  • 在使用接口时, 再指定具体的泛型类型
// 定义一个泛型接口
interface IBaseCRUD<T> {
   // 数据
   data: Array<T>       //data: T[]
   // 添加用户信息
   // 注意:传的值为t,传值的类型是T,整个函数返回值是T
   add: (t: T) => T
   // 根据id获取指定的用户信息
   getUserId: (id: number) => T
}

// 1.定义一个用户信息的类
class User {
   id?: number,
   name: string,
   age: number,
   constructor(name: string, age: number){
       this.name = name
       this.age = age
   }
}

// 2.定义一个类,可以针对用户的信息对象进行增加及查询的操作
// 类和接口之间叫实现(使用的是implements)
class UserCRUD implements IBaseCRUD<User> {
    // 用来保存多个User类型的用户信息对象
    data: Array<User> = []
    //方法用来存储用户信息对象的
    add(user: User): User {
      // 产生id
      user.id = Date.now() + Math.random()
      this.data.push(user)
      return user
    }
   // 方法根据id查询指定的用户信息对象
   getUserId(id: number): User {
       return this.data.find(user => user.id === id)
   }
}


// 实例化添加用户信息对象的类UserCRUD
const userCRUD: UserCRUD = new UserCRUD()
// 调用添加数据的方法
userCRUD.add(new User('栗子', 18))
const { id } = userCRUD.add(new User('诺诺', 20))
// 根据id查询用户信息对象数据
const user = userCRUD.getUserId(id)
console.log(user)

泛型类

  • 在定义类时, 为类中的属性或方法定义泛型类型,在创建类的实例时, 再指定特定的泛型类型
// 定义一个类,类中属性值的类型是不确定,方法中参数及返回值的类型也是不确定
// 定义一个泛型类
class GenericNumber<T> {
   // 默认的属性值的类型是泛型类型  
   defaultValue: T
   add: (x: T, y: T) => T
}

// 在实例化类的对象的时候,再确定泛型的类型
const g1: GenericNumber<number> = new GenericNumber<number>()
// 设置属性值
g1.defaultValue = 666
// 相加的方法
g1.add = function (x, y) {
    return x + y
}

泛型约束

  • 如果直接对一个泛型参数取 length 属性, 就会报错, 因为这个泛型根本就不知道它有这个属性,这种情况下可以使用泛型约束来实现
// 定义一个接口,用来约束将来的某个类型中必须要有length这个属性
interface ILength {
   // 接口中有一个属性length
   length: number  
}

// 定义函数
function getLength<T extends ILength>(x: T): number {
    return x.length
}
console.log(getLength<string>('what are you no sha lei'))
// console.log(getLength<number>(123))      //注意:number没有length属性