Typescript中能否实现嵌套泛型约束,仅传单个泛型参数满足类型校验?
可以实现,你可以通过 TypeScript 条件类型的 infer 关键字提取 Entity 中嵌套的 ID 类型,仅需传入一个实体泛型参数即可满足所有约束要求。
第一步:定义ID提取工具类型
首先实现一个工具类型,从符合约束的 Entity 子类中自动提取对应的 ID 类型:
// TS 4.7 及以上版本写法 type ExtractEntityId<T extends Entity<any>> = T extends Entity<infer TId extends Id> ? TId : never;
如果使用低于 4.7 版本的 TypeScript,不支持 infer 后直接加约束,可以调整为以下写法,效果完全一致:
// 兼容旧版本 TS 的写法 type ExtractEntityId<T extends Entity<any>> = T extends Entity<infer TId> ? TId extends Id ? TId : never : never;
以上两种写法都会自动校验 Entity 的泛型参数是否符合 Id 约束,不符合要求的类型会直接返回 never 触发类型报错。
第二步:实现单泛型参数的 Repository 类
class GenericRepository<TEntity extends Entity<any>> { update(entity: TEntity): void { // 你的业务实现逻辑 } get(id: ExtractEntityId<TEntity>): TEntity { // 你的业务实现逻辑 } }
效果验证
你可以直接按照预期仅传入实体类型完成实例化,类型约束会自动生效:
// 仅需传入一个泛型参数即可 const productRepo = new GenericRepository<ProductEntity>(); // 类型校验正常生效 productRepo.get(new ProductId()); // 合法,ID 类型匹配 productRepo.get(new OtherId()); // 报错,ID 类型不匹配 productRepo.update(new ProductEntity()); // 合法
内容的提问来源于stack exchange,提问作者Brandon P.
相关产品推荐
相关产品推荐

