泛型的定义
泛型:软件工程中,我们不仅要创建一致的定义良好的 API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像 C#和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
只能返回 string 类型的数据
1 2 3
| function getData(value: string): string { return value; }
|
同时返回 string 类型 和 number 类型 (代码冗余)
1 2 3 4 5 6 7
| function getData1(value: string): string { return value; }
function getData2(value: number): number { return value; }
|
同时返回 string 类型 和 number 类型 any 可以解决这个问题
any
放弃了类型检查,传入什么 返回什么。比如:传入 number 类型必须返回 number 类型 传入 string 类型必须返回 string 类型
1 2 3 4 5 6 7
| function getData(value: any): any { return "哈哈哈"; }
getData(123);
getData("str");
|
传入的参数类型和返回的参数类型可以不一致
1 2 3
| function getData(value: any): any { return "哈哈哈"; }
|
泛型函数
可以支持不特定的数据类型 要求:传入的参数和返回的参数一直
T
表示泛型,具体什么类型是调用这个方法的时候决定的
基础用法
1 2 3 4 5 6 7 8
| function getData<T>(value: T): T { return value; } getData<number>(123);
getData<string>("1214231");
getData<number>("2112");
|
1 2 3 4 5 6 7
| function getData<T>(value: T): any { return "2145214214"; }
getData<number>(123);
getData<string>("这是一个泛型");
|
1 2 3 4 5
| function join<T>(first: T, second: T) { return `${first} ${second}`; } join<number>(1, 2); join<string>("a", "b");
|
多个泛型的定义
1 2 3 4 5 6
| function joinMul<T, P>(first: T, second: P) { return `${first} ${second}`; } joinMul<string, number>("a", 2);
joinMul("a", 2);
|
泛型中数组的使用
1 2 3 4 5 6
| function arrFun<T>(params: Array<T>) { return params; }
arrFun<number>([1, 2]); arrFun<string>(["a", "b"]);
|
泛型类
基础用法
例:比如有个最小堆算法,需要同时支持返回数字和字符串 a - z 两种类型。 通过类的泛型来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class MinClass { public list: number[] = []; add(num: number) { this.list.push(num); } min(): number { var minNum = this.list[0]; for (var i = 0; i < this.list.length; i++) { if (minNum > this.list[i]) { minNum = this.list[i]; } } return minNum; } }
var m = new MinClass();
m.add(3); m.add(22); m.add(23);
alert(m.min());
|
类的泛型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class MinClas<T> { public list: T[] = [];
add(value: T): void { this.list.push(value); }
min(): T { var minNum = this.list[0]; for (var i = 0; i < this.list.length; i++) { if (minNum > this.list[i]) { minNum = this.list[i]; } } return minNum; } }
var m1 = new MinClas<number>(); m1.add(11); m1.add(3); m1.add(2); alert(m1.min());
var m2 = new MinClas<string>();
m2.add("c"); m2.add("a"); m2.add("v"); alert(m2.min());
|
例:获取用户身份
1 2 3 4 5 6 7 8 9
| class Id<T> { constructor(private people: T[]) {} getId(index: number): T { return this.people[index]; } }
const userId = new Id<string>(["教师", "学生", "医生"]); console.log(userId.getId(0));
|
泛型中的继承
interface 接口定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| interface IdModel { name: string; }
class IdExtends<T extends IdModel> { constructor(private people: T[]) {} getId(index: number): string { return this.people[index].name; } }
const userIdExtends = new IdExtends<IdModel>([ { name: "教师" }, { name: "学生" }, { name: "医生" } ]);
console.log(userIdExtends.getId(1));
|
泛型类型约束
1 2 3 4 5 6 7 8 9
| class GenConstraint<T extends number | string> { constructor(private people: T[]) {} getId(index: number): T { return this.people[index]; } }
const userGenConstraint = new GenConstraint<string>(["教师", "学生", "医生"]); console.log(userId.getId(2));
|
泛型接口
1 2 3 4 5 6 7 8 9 10 11
| interface ConfigFn { <T>(value: T): T; }
var getData: ConfigFn = function <T>(value: T): T { return value; };
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface ConfigFn<T> { (value: T): T; }
function getData<T>(value: T): T { return value; }
var myGetData: ConfigFn<string> = getData;
myGetData("20");
|