05、TypeScript 中的泛型

 

泛型:软件工程中,我们不仅要创建一致的定义良好的 API,同事也要考虑可重用性,组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。在像 C++ 和 java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据,这样用户就可以以自己的数据类型来使用组件

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持

1.泛型函数及泛型定义

// 1.方法中泛型的定义
// 只能返回 string 类型
function getData(value: string): string {
  return value;
}

// 同时返回 string 类型 和 number 类型 (代码冗余)
function getData1(value: string): string {
  return value;
}

function getData2(value: number): number {
  return value;
}

// 同时返回 string 类型 和 number 类型
// any 是放弃了类型检查(没有类型校验),这里可以返回任何值,和我们预期不一样,要求是传入什么返回什么类型
function getData3(value: any): any {// 这里传入和返回类型可以不一致
  return value;
  // return '哈哈哈哈哈';
}

// 通过泛型:T 表示泛型,具体什么类型是调用这个方法的时候决定的
function getData6<T>(value: T): T {
  return value;
  // return 'aaa';// 这里不能返回固定的类型,我们还不确定要返回什么类型,
}

getData6<number>(123);// 这里控制传递的类型
getData6<string>('123');

 

2.泛型类

// 2.泛型类:比如有个最小堆算法,需要同时支持返回数字和字符串两种类型。
// 定义泛型类,可以指定任意类型,any 也可以实现,但是没有类型校验,这里有类型校验
class MinClass<T> {
  list: T[] = [];

  add(num: T) {
    this.list.push(num);
  }

  min(): T {
    let minNum = this.list[0];
    for (let i = 0; i < this.list.length; i++) {
      if (minNum > this.list[i]) {
        minNum = this.list[i];
      }
    }
    return minNum;
  }
}

let m = new MinClass<number>();
m.add(2);
m.add(222);
m.add(22);
m.add(23);
console.log(m.min());// 获得最小数

let m1 = new MinClass<string>();
m1.add('22');
m1.add('23');
m1.add('222');
m1.add('223');
console.log(m1.min());

 

3.泛型接口

// 3.泛型接口
// 第一种定义泛型函数接口方法
interface ConfigFn {
  <T>(value1: T): T;
}

var setData: ConfigFn = function <T>(v1: T): T {
  return v1;
};
// 在这里指定类型
console.log(setData<string>('zhang'));

// 第二种定义泛型函数接口方法
interface ConfigFn1<T> {
  (value: T): T;
}

function getData11<T>(value: T): T {
  return value;
}

var myGetData: ConfigFn1<string> = getData11;

myGetData('20');

 

4.泛型类,把类当作参数的泛型类

//4.泛型类,把类当作参数的泛型类
/*
定义一个 User 的类,这个类的作用就是映射数据库字段,然后定义一个 MysqlDb 的类,这个类用于操作数据库,然后把 user 类作为参数传入到 MysqlDb 中
*/

// 定义 User 类,和数据库进行映射
class User {
  username: string | undefined;
  password: string | undefined;
}

class MysqlDb<T> {
  add(info: T): boolean {
    console.log(info);
    return true;
  }
}

let u = new User();
u.username = 'zhangning';
u.password = 'ningning';

let Db = new MysqlDb<User>();
Db.add(u);// 这里会验证是否符合 User 类

// 定义 ArticleCate 类和数据库进行映射
class ArticleCate {
  title: string | undefined;
  desc: string | undefined;
  status: number | undefined;

  constructor(props: {// 实例化的时候,传值验证
    title: string | undefined,
    desc: string | undefined,
    status?: number | undefined
  }) {
    this.title = props.title;
    this.desc = props.desc;
    this.status = props.status;
  }
}

var a = new ArticleCate({ title: '分类', desc: '1111' });
let Dba = new MysqlDb<ArticleCate>();
Dba.add(a);

 

posted @ 2021-04-12 16:57  张_Ning  阅读(91)  评论(0编辑  收藏  举报