TypeScript 类、泛型的使用实践记录
1. 泛型函数
泛型函数是使用泛型的常见方式之一,它允许你编写适用于不同类型的数据的函数。例如,下面是一个简单的泛型函数,用于交换两个变量的值:
function swap<T>(a: T, b: T): void {
let temp: T = a;
a = b;
b = temp;
}
let x = 5, y = 10;
swap(x, y); // x 现在是 10,y 现在是 5
2. 类中的泛型
泛型也可以在类中使用,允许你在类中处理不同类型的数据。例如,下面是一个简单的泛型类,用于创建一个存储任意类型元素的堆栈:
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
const numberStack = new Stack<number>();
numberStack.push(5);
numberStack.push(10);
console.log(numberStack.pop()); // 输出 10
const stringStack = new Stack<string>();
stringStack.push("Hello");
stringStack.push("World");
console.log(stringStack.pop()); // 输出 "World"
3. 泛型约束
有时候,你希望对泛型参数施加一些限制,以确保代码的安全性和正确性。这就是泛型约束的用途。例如,你可以使用泛型约束来要求传入的类型具有某些属性或方法:
interface Lengthable {
length: number;
}
function printLength<T extends Lengthable>(item: T): void {
console.log(item.length);
}
printLength("Hello"); // 输出 5
printLength([1, 2, 3]); // 输出 3
4. 使用默认类型
你还可以为泛型参数提供默认类型,以便在调用时如果没有显式指定类型,就会使用默认类型:
function getValueOrDefault<T = number>(value: T, defaultValue: T): T {
return value !== undefined ? value : defaultValue;
}
const result = getValueOrDefault(undefined, 10); // 默认为 10
5. 多个泛型参数
函数、类等可以有多个泛型参数,用途从而变得更加灵活。例如:
function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
const merged = merge({ a: 1 }, { b: 2 });
// merged 的类型为 { a: number, b: number }
在 TypeScript 中,泛型的使用能够帮助你更好地抽象和重用代码,同时也能提供更强的类型安全性。根据具体的场景,你可以选择合适的泛型使用方式以及是否需要使用类型约束,从而提高代码的质量和可维护性。