TypeScript中如何定义可适配泛型父类型的泛型类型?
问题描述
我参考了某个Stack Overflow解决方案,想进一步优化使其更通用,于是写了如下泛型类型:
export type extractGeneric<Type, Parent> = Type extends Parent<infer Entity> ? Entity : never
但TypeScript报错:
Type 'Parent' is not generic.ts(2315)
官方方案是硬编码Repository类型,示例如下:
import { Repository } from "typeorm" export type extractGeneric<Type> = Type extends Repository<infer Entity> ? Entity : never
请问如何解决该报错,实现可适配任意泛型父类型的泛型类型?
解决方案
要解决这个问题,核心是明确告诉TypeScript:Parent本身是一个可以接受类型参数的泛型类型/构造器。TypeScript默认不会把泛型参数Parent当成泛型类型处理,所以需要给它添加明确的约束。
通用泛型类型实现
// 约束Parent为接受单个类型参数的泛型构造器/类型函数 export type ExtractGeneric<Type, Parent extends <T>() => T> = Type extends ReturnType<Parent<infer Entity>> ? Entity : never;
使用示例
以TypeORM的Repository为例测试:
import { Repository } from "typeorm"; // 定义一个示例实体类型 type User = { id: number; name: string }; // 生成该实体对应的Repository类型 type UserRepository = Repository<User>; // 提取Repository中的泛型实体类型 type ExtractedUser = ExtractGeneric<UserRepository, typeof Repository>; // 此时ExtractedUser会被正确推断为User类型
原理说明
- 给
Parent添加<T>() => T约束,明确它是一个接受任意类型参数T、并返回对应类型的泛型构造器或类型函数。 - 通过
ReturnType<Parent<infer Entity>>语法,让TypeScript自动推断出Parent所接受的类型参数Entity,也就是我们需要提取的泛型类型。
如果你的泛型父类型是自定义泛型别名而非类,只需根据实际情况微调约束即可适配。
内容的提问来源于stack exchange,提问作者Islam Y-
相关产品推荐
相关产品推荐

