什么是泛型(generics)?
所谓泛型简单理解就是: 宽泛的类型
, 在定义的时候不知道是什么类型, 在使用的时候再指定类型
为什么要使用泛型?
举个例子: 实现一个填充数组函数的方法, 可以传入 2 个参数, 第一个参数代表填充的个数, 第二个参数代表要填充的值, 第二个参数的值可以是任意类型, 且必须有类型约束
typescript
// 如果这样子实现的话, 第二个参数没有约束类型
// function fillArray(count: number, data: any): any[] {}
// 传入的 <T> 是什么类型, 那么 result 的 Array<T> 就是什么类型
function fillArray<T>(count:number, data:<T>): Array<T> {
const result:Array<T> = []; // Array<T> 也可以使用 T[] 这种形式
for (let i = 0; i< count; i++) {
result.push(data);
}
return result;
}
fillArray(5, "hello");
// 也可以手动指定泛型的类型 fillArray<string>(5, "hello")
泛型继承
- 要求传入的第二个参数必须要有
length
属性
typescript
interface ILength {
length: number;
}
function fillArray<T extends ILength>(count:number, data:<T>): Array<T> {
const result:Array<T> = [];
for (let i = 0; i< count; i++) {
result.push(data);
}
return result;
}
fillArray(3, "1"); // 字符串有 length 属性
fillArray(3, [1]); // 数组也有 length 属性
fillArray(3, { length: 1, hello: "world" });// 传入的对象有 length 属性
fillArray(3, { hello: "world" }); // 传入对象没有 length 属性, 所以会报错
fillArray(3, 1); // 数字没有 length 属性, 所以会报错
在类中使用泛型(泛型类)
typescript
interface ICacheMaanger {
caches: Array<any>;
add(val: any): void;
all(): any[];
}
// 不使用泛型 -----
class NumberCacheMgr implements ICacheManager {
caches: number[] = [];
add(val: number): void {
this.caches.push(val);
}
all(): number[] {
return this.caches;
}
}
class StringCacheMgr implements ICacheManager {
caches: string[] = [];
add(val: string): void {
this.caches.push(val);
}
all(): string[] {
return this.caches;
}
}
// 以上代码可以发现, 除了类型不一样, 其他所有的处理都是一样的
// 此时, 就可以使用泛型, 在使用的时候再确定类型
// 使用泛型 -----
class CacheManager implements ICacheManager {
private caches: T[] = [];
add(val: T): void {
this.caches.push(val);
}
all(): T[] {
return this.caches;
}
}
const numCacheMgr = new CacheManager<number>();
numCacheMgr.add(1);
numCacheMgr.add(3);
// numCacheMgr.add("hello"); // 报错
const strCacheMgr = new CacheManager<string>();
strCacheMgr.add('hello');
strCacheMgr.add('world');
// strCacheMgr.add(true); // 报错
const userCacheMgr = new CacheManager<{ id: number; email: string }>();
userCacheMgr.add({ id: 1001, email: 'tom@qq.com' });
userCacheMgr.add({ id: 1002, email: 'jerry@qq.com' });
类型别名使用泛型
typescript
type Position<T> = { x: T; y: T };
const p1: Position<string> = { x: '10px', y: '10px' };
const p2: Position<number> = { x: 30, y: 50 };