软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。
组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
泛型(Generics),从字面上理解,泛型就是一般的,广泛的。泛型是指在定义函数、接口或类的时候,不预先指定具体类型,而是在使用的时候再指定类型。
泛型中的
T就像一个占位符、或者说一个变量,在使用的时候可以把定义的类型像参数一样传入,它可以原封不动地输出。泛型在成员之间提供有意义的约束,这些成员可以是:函数参数、函数返回值、类的实例成员、类的方法等。
泛型基本使用
function echo<T>(arg: T): T {
return arg;
}
const result = echo(true);
交换数组位置
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
const result = swap(["string", 123]);
使用泛型变量
function echoWithArr<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
const arr = echoWithArr([1, 2, 3]);
// const string = echoWithArr(123)
泛型约束
interface IWithLength {
length: number;
}
function echoWithLength<T extends IWithLength>(arg: T): T {
console.log(arg.length);
return arg;
}
const str = echoWithLength("str");
const obj = echoWithLength({ length: 10, width: 10 });
const arr = echoWithLength([1, 2, 3]);
队列
class Queue<T> {
private data: T[] = [];
push(item: T) {
return this.data.push(item);
}
pop(): T | undefined {
return this.data.shift();
}
}
const queue = new Queue<number>();
queue.push(1);
console.log(queue.pop()?.toFixed()); // 1
const queue2 = new Queue<string>();
queue2.push("sunshine");
console.log(queue2.pop()?.length); // 8
泛型类型
interface KeyPair<T, U> {
key: T;
value: U;
}
let kp1: KeyPair<number, string> = { key: 123, value: "str" };
let kp2: KeyPair<string, number> = { key: "age", value: 99 };
let arr: number[] = [1, 2, 3];
let arrTwo: Array<number> = [1, 2, 3];
interface IPlus<T> {
(a: T, b: T): T;
}
function puls(a: number, b: number): number {
return a + b;
}
function connent(a: string, b: string): string {
return a + b;
}
const a: IPlus<number> = puls;
const b: IPlus<string> = connent;