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);