05-TS的泛型

01-泛型

//! 泛型:在定义函数、接口、类的时候不能预先确定数据的类型,
//!       而是在使用函数、接口、类的时候才能确定数据的类型
(() => {
  /**
   * *需求:定义一个函数,传入两个参数,第一参数是数据,第二个参数是数量
   * *函数的作用:根据数量产生对应个数的数据,放在一个数组中
   */
  //定义函数
  function getArr<T>(num: T, count: number): T[] {
    //根据数据和数量产生一个数组
    //const array: T[] = [];
    const array: Array<T> = [];
    for (let i = 0; i < count; i++) {
      array.push(num);
    }
    return array;
  }
  const arr1 = getArr<number>(100.123, 3);
  console.log("arr1: ", arr1);
  console.log(arr1[0].toFixed(1));

  const arr2 = getArr<string>("abc", 4);
  console.log("arr2: ", arr2);
  console.log("11", arr2[0].split(""));
})();

复制代码

02-多个泛型的参数

// ! 多个泛型参数的函数 函数中有多个泛型的参数
(() => {
  function name<K, V>(value1: K, value2: V): [K, V] {
    return [value1, value2];
  }
  const arr1 = name<string, number>("嗷嗷", 18);
  console.log("arr1: ", arr1); 
})();

复制代码

03-泛型接口

// ! 泛型接口
/**
 * * 在定义接口时, 为接口中的属性或方法定义泛型类型
 * * 在使用接口时, 再指定具体的泛型类型
 */
(() => {
  /**
   * * 定义一个类,用来存储用户的相关信息(id,名字,年龄)
   * * 通过一个类的实例对象,调用add方法,可以添加多个用户信息对象
   * * 调用 getUserId可以根据id获取某个指定的用户信息对象
   */
  //? 定义一个泛型接口
  interface IBaseCRUD<T> {
    data: Array<T>;
    add: (t: T) => T;
    getUserId: (id?: number) => T | undefined;
  }
  //? 定义一个用户信息的类
  class User {
    id?: number;
    name: string;
    age: number;
    constructor(name: string, age: number) {
      this.name = name;
      this.age = age;
    }
  }
  //? 定义一个可以针对用户的信息对象进行增加及查询的操作
  //! CRUD---->create,read,update,delete
  class UserCRUD implements IBaseCRUD<User> {
    data: Array<User> = [];
    //存储用户信息对象
    add(user: User): User {
      // 生成id
      user.id = Date.now() + Math.random();
      // 把用户信息对象添加到data
      this.data.push(user);
      return user;
    }
    //根据id查询指定的用户信息对象
    getUserId(id?: number): User | undefined {
      return this.data.find((user) => user.id === id);
    }
  }
  //实例化添加用户信息对象的类UserCRUD
  const userRUD: UserCRUD = new UserCRUD();
  console.log(userRUD.data);
  userRUD.add(new User("名字", 20));
  const { id } = userRUD.add(new User("名字1", 21));
  userRUD.add(new User("名字2", 22));
  //? 根据id查询指定的用户信息对象
  const user = userRUD.getUserId(id);
  console.log("user: ", user);
})();

复制代码

04-泛型类

//! 泛型类
/**
 * * 定义一个类,类中的属性值的类型不确定
 * * 方法中的参数的类型也不确定
 */
(() => {
  class GenericNumber<T> {
    defaultValue?: T;
    add?: (x: T, y: T) => T;
    constructor(defaultValue?: T, add?: (x: T, y: T) => T) {
      if (defaultValue && add) {
        this.defaultValue = defaultValue;
        this.add = add;
      }
    }
  }
  //? 在实例化对象的时候,再确定泛型的类型
  const g1: GenericNumber<number> = new GenericNumber<number>();
  //? 设置属性值
  g1.defaultValue = 100;
  //? 添加的方法
  g1.add = function (x, y) {
    return x + y;
  };

  console.log(g1.add(10, 20));

  //? 在实例化对象的时候,再确定泛型的类型
  const g2: GenericNumber<string> = new GenericNumber<string>();
  //? 设置属性值
  g2.defaultValue = "100";
  //? 添加的方法
  g2.add = function (x, y) {
    return x + y;
  };
  console.log(g2.add("10", "10"));
})();

复制代码

05-泛型的约束

//! 泛型的约束
//! 如果我们直接对一个泛型参数取 length 属性, 会报错, 因为这个泛型根本就不知道它有这个属性
(() => {
  //? 定义一个接口 用来约束将来的某个类型中必须要有length这个属性
  interface ILength {
    length: number;
  }
  function getLength<T extends ILength>(x: T): number {
    return x.length;
  }
  console.log(getLength<string>("123"));
  //console.log(getLength<number>(123));
})();

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享