在日常开发中,TypeScript 的泛型和类提供了灵活的工具,用于提升代码的复用性和安全性。通过简单的笔记形式,这里将从基础概念到具体实践,介绍如何使用 TypeScript 的类和泛型。
1. 泛型是什么?
泛型 是一种允许类型参数化的机制,让代码能够处理多种类型,而不需要重复实现。
核心特点:
- 灵活性:适配多种类型。
- 安全性:提供静态类型检查,避免运行时错误。
简单例子:
function wrap<T>(value: T): T {
return value;
}
console.log(wrap<number>(10)); // 输出: 10
console.log(wrap<string>("Hello")); // 输出: Hello
我的理解:
通过 <T>,我们可以在编译时告诉函数应处理什么类型,这样既省去了类型转换的麻烦,也让函数更加通用。
2. 泛型与类的结合
在开发中,经常会设计一些工具类,比如栈、队列、缓存等,这些场景中,泛型与类的结合尤其重要。
实践:使用泛型实现一个简单的栈
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
const numberStack = new Stack<number>();
numberStack.push(10);
numberStack.push(20);
console.log(numberStack.pop()); // 输出: 20
我的理解:
相比直接使用 any,泛型 T 让栈明确了所处理的数据类型,既灵活又安全。
3. 类型约束的使用
泛型虽灵活,但也可能过于宽泛。这时,可以通过 类型约束 来限制泛型的适用范围。
实践:实现一个排序工具
interface HasId {
id: number;
}
function sortById<T extends HasId>(items: T[]): T[] {
return items.sort((a, b) => a.id - b.id);
}
const data = [
{ id: 3, name: "Alice" },
{ id: 1, name: "Bob" },
{ id: 2, name: "Charlie" },
];
console.log(sortById(data));
// 输出: [{ id: 1, name: "Bob" }, { id: 2, name: "Charlie" }, { id: 3, name: "Alice" }]
我的理解:
- 通过
T extends HasId,确保传入的对象一定有id属性。 - 这种写法提高了代码健壮性,避免了不符合预期的输入。
4. 泛型的实际应用:缓存系统
在项目中,经常需要缓存不同类型的数据。通过泛型和类,可以实现一个简洁而安全的数据缓存工具。
代码实现:
class DataCache<T> {
private cache: Map<string, T> = new Map();
set(key: string, value: T): void {
this.cache.set(key, value);
}
get(key: string): T | undefined {
return this.cache.get(key);
}
}
const userCache = new DataCache<{ id: number; name: string }>();
userCache.set("user1", { id: 1, name: "Alice" });
console.log(userCache.get("user1")); // 输出: { id: 1, name: 'Alice' }
我的体会:
这类缓存工具不仅简化了数据存储逻辑,还通过泛型确保了数据类型的正确性,减少运行时错误。
5. 我学到的泛型使用场景总结
- 通用工具类:如栈、队列、缓存等。
- 特定约束的工具函数:如带类型限制的排序、过滤工具。
- 代码复用:避免重复为不同类型实现类似逻辑。
需要注意的问题:
- 过度泛型:如果场景过于简单,不建议使用泛型,因为可能增加代码复杂度。
- 合理的类型约束:让泛型代码既灵活又不失安全性。
6. 总结
在 TypeScript 中,泛型与类是非常强大的工具,它们不仅能提升代码的灵活性,还能在编译阶段提供类型检查,提高开发效率。在实践中,我深刻体会到,合理使用泛型,可以让代码更加简洁、高效、安全。
我的建议:
- 从简单场景入手练习泛型。
- 在实际项目中,思考是否需要类型约束,以及如何设计更通用的类或函数。