如何在TypeScript中复用类定义并维持类型严格性?
用TypeScript泛型实现DRY原则,同时保留类型严谨性
这正是TypeScript泛型的核心应用场景!你不需要重复编写几乎一模一样的类,只需要创建一个通用泛型类,把Client、Product这类具体实体类型作为类型参数传入,就能用一份代码处理所有同类逻辑,同时完全保留TypeScript的类型检查能力。
通用泛型类实现
class EntityDB<T> { DB: Database; replaySubject = new ReplaySubject<T[]>(1); constructor(name: string) { this.DB = new Database(name); } up() { fromPromise(this.DB.getDocs<T>()) .subscribe((entities) => this.replaySubject.next(entities)); } subscribe(callback: (value: T[]) => void) { return this.replaySubject.subscribe(callback); } }
如何使用这个通用类
现在你可以轻松创建针对Client和Product的实例,或者用类型别名给它们起更语义化的名字:
// 方式1:直接创建实例 const clientsDB = new EntityDB<Client>('clients'); const productsDB = new EntityDB<Product>('products'); // 方式2:用类型别名定义专属类型(更贴近你原来的类命名风格) type ClientsDB = EntityDB<Client>; type ProductsDB = EntityDB<Product>; const clientsDB = new ClientsDB('clients'); const productsDB = new ProductsDB('products');
关键细节说明
- 泛型参数
<T>会贯穿整个类的定义:从ReplaySubject<T[]>到getDocs<T>(),再到subscribe的回调参数(value: T[]) => void,TypeScript会自动根据你传入的具体类型(比如Client)进行类型推断和检查。 - 这样做完全遵循DRY原则:如果后续需要添加
OrdersDB,只需要new EntityDB<Order>('orders')即可,不需要复制粘贴整个类代码。 - 类型严谨性丝毫未减:比如当你调用
clientsDB.subscribe()时,TypeScript会强制要求回调函数的参数是Client[]类型,避免类型错误。
可选:给泛型添加约束(如果需要)
如果你的所有实体类型都有共同的属性(比如id),可以给泛型添加约束,确保传入的类型符合要求:
// 定义实体的基础约束 interface BaseEntity { id: string; } // 泛型类只接受符合BaseEntity的类型 class EntityDB<T extends BaseEntity> { // ... 其余代码不变 }
这样就完美解决了重复代码的问题,同时保持了TypeScript的类型安全特性!
内容的提问来源于stack exchange,提问作者PaulCo
相关产品推荐
相关产品推荐

