美文网首页
TypeScript系列(六):泛型

TypeScript系列(六):泛型

作者: 黑白i | 来源:发表于2022-05-23 08:48 被阅读0次

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

    引入

    下面创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 创建一个包含 count 个 value 的数组 不用泛型的话,这个函数可能是下面这样:

    function createArray(value: any, count: number): any[] {
      const arr: any[] = []
      for (let index = 0; index < count; index++) {
        arr.push(value)
      }
      return arr
    }
    
    const arr1 = createArray(11, 3)
    const arr2 = createArray('aa', 3)
    console.log(arr1[0].toFixed(), arr2[0].split(''))
    

    使用函数泛型

    function createArray2 <T> (value: T, count: number) {
      const arr: Array<T> = []
      for (let index = 0; index < count; index++) {
        arr.push(value)
      }
      return arr
    }
    const arr3 = createArray2<number>(11, 3)
    console.log(arr3[0].toFixed())
    // console.log(arr3[0].split('')) // error
    const arr4 = createArray2<string>('aa', 3)
    console.log(arr4[0].split(''))
    // console.log(arr4[0].toFixed()) // error
    

    多个泛型参数的函数

    一个函数可以定义多个泛型参数

    function swap <K, V> (a: K, b: V): [K, V] {
      return [a, b]
    }
    const result = swap<string, number>('abc', 123)
    console.log(result[0].length, result[1].toFixed())
    

    泛型接口

    在定义接口时, 为接口中的属性或方法定义泛型类型
    在使用接口时, 再指定具体的泛型类型

    interface IbaseCRUD <T> {
      data: T[]
      add: (t: T) => void
      getById: (id: number) => T
    }
    
    class User {
      id?: number; //id主键自增
      name: string; //姓名
      age: number; //年龄
    
      constructor (name, age) {
        this.name = name
        this.age = age
      }
    }
    
    class UserCRUD implements IbaseCRUD <User> {
      data: User[] = []
      
      add(user: User): void {
        user = {...user, id: Date.now()}
        this.data.push(user)
        console.log('保存user', user.id)
      }
    
      getById(id: number): User {
        return this.data.find(item => item.id===id)
      }
    }
    
    const userCRUD = new UserCRUD()
    userCRUD.add(new User('tom', 12))
    userCRUD.add(new User('tom2', 13))
    console.log(userCRUD.data)
    

    泛型类

    在定义类时, 为类中的属性或方法定义泛型类型 在创建类的实例时, 再指定特定的泛型类型

    class GenericNumber<T> {
      zeroValue: T
      add: (x: T, y: T) => T
    }
    
    let myGenericNumber = new GenericNumber<number>()
    myGenericNumber.zeroValue = 0
    myGenericNumber.add = function(x, y) {
      return x + y 
    }
    
    let myGenericString = new GenericNumber<string>()
    myGenericString.zeroValue = 'abc'
    myGenericString.add = function(x, y) { 
      return x + y
    }
    
    console.log(myGenericString.add(myGenericString.zeroValue, 'test'))
    console.log(myGenericNumber.add(myGenericNumber.zeroValue, 12))
    

    泛型约束

    如果我们直接对一个泛型参数取 length 属性, 会报错, 因为这个泛型根本就不知道它有这个属性

    // 没有泛型约束
    function fn <T>(x: T): void {
      // console.log(x.length)  // error
    }
    

    我们可以使用泛型约束来实现

    interface Lengthwise {
      length: number;
    }
    
    // 指定泛型约束
    function fn2 <T extends Lengthwise>(x: T): void {
      console.log(x.length)
    }
    

    我们需要传入符合约束类型的值,必须包含必须 length 属性:

    fn2('abc')
    // fn2(123) // error  number没有length属性
    

    相关文章

      网友评论

          本文标题:TypeScript系列(六):泛型

          本文链接:https://www.haomeiwen.com/subject/pomtprtx.html