TypeScript并行类型层级的通用实例创建方案问询
TypeScript并行类层级的实例映射创建方案
针对你提到的并行类层级(如MVVM中ViewModel与View的对应),可以通过类型注册表的方式实现通用的实例创建逻辑,既解耦类之间的依赖,又避免大量条件判断。
核心思路
通过一个注册表存储A类(ViewModel)构造函数到对应B类(View)构造函数的映射,在创建实例时根据A实例的构造函数查找对应的B构造函数,完成实例化。
代码实现
1. 基础类型与注册表定义
首先定义构造函数的类型别名,并创建映射注册表:
class A {} class A1 extends A {} class A2 extends A {} class B<TypeA extends A> { a: TypeA; constructor(a: TypeA) { this.a = a; } } class B1 extends B<A1> {} class B2 extends B<A2> {} // 定义A类构造函数的类型 type AConstructor<T extends A> = new () => T; // 定义对应B类构造函数的类型 type BConstructor<T extends A> = new (a: T) => B<T>; // 注册表:存储A构造函数到B构造函数的映射 const aToBRegistry = new Map<AConstructor<A>, BConstructor<A>>();
2. 注册映射关系
提供注册函数,用于绑定A子类与对应B子类的关系:
function registerB<T extends A>(aCtor: AConstructor<T>, bCtor: BConstructor<T>) { aToBRegistry.set(aCtor, bCtor); } // 批量注册(可放在单独模块中,避免A类依赖B类) registerB(A1, B1); registerB(A2, B2); // ... 依次注册A3~A100与B3~B100的映射
3. 通用创建函数
实现create函数,根据A实例查找对应B类并创建实例:
function create<T extends A>(aInstance: T): B<T> { // 获取A实例的构造函数 const aCtor = aInstance.constructor as AConstructor<T>; // 从注册表中查找对应的B构造函数 const bCtor = aToBRegistry.get(aCtor) as BConstructor<T>; if (!bCtor) { throw new Error(`未找到与${aCtor.name}对应的B类实现`); } return new bCtor(aInstance); }
4. 使用示例
const b1 = create(new A1()); // 类型自动推断为B1实例 const b2 = create(new A2()); // 类型自动推断为B2实例
MVVM场景适配
将上述逻辑迁移到App类的#createView方法中,适配ViewModel与View的创建需求:
// 假设的ViewModel与View基类 abstract class ViewModel {} abstract class View<T extends ViewModel> { constructor(public viewModel: T) {} } // 示例子类 class UserViewModel extends ViewModel {} class UserView extends View<UserViewModel> {} class App { // 私有注册表,存储ViewModel到View的映射 #vmToViewRegistry = new Map<new () => ViewModel, new (vm: ViewModel) => View<ViewModel>>(); // 对外提供注册View的方法 registerView<T extends ViewModel>(vmCtor: new () => T, viewCtor: new (vm: T) => View<T>) { this.#vmToViewRegistry.set(vmCtor, viewCtor); } // 私有方法:根据ViewModel实例创建对应View #createView<T extends ViewModel>(vmInstance: T): View<T> { const vmCtor = vmInstance.constructor as new () => T; const viewCtor = this.#vmToViewRegistry.get(vmCtor) as new (vm: T) => View<T>; if (!viewCtor) { throw new Error(`未找到与${vmCtor.name}对应的View实现`); } return new viewCtor(vmInstance); } }
方案优势
- 解耦依赖:A类(ViewModel)无需知晓B类(View)的存在,注册逻辑可独立维护
- 扩展性强:新增子类仅需调用
registerB/registerView,无需修改创建函数 - 类型安全:TypeScript可自动推断返回实例的类型,避免类型错误
内容的提问来源于stack exchange,提问作者vers
相关产品推荐
相关产品推荐

