TypeScript泛型工厂问题:避免typeof自动添加到泛型参数
泛型工厂类型不匹配问题
我尝试创建一个基于泛型的工厂函数,传入类用于后续实例化,但遇到了TypeScript自动修改泛型类型的问题。以下是最小复现代码:
export interface Repository<T> { add(data: T): Promise<void>; } export const createRepository = <T>(schema: T) => (): Repository<T> => ({ async add(data) { // 业务逻辑 }, }); // 示例类,可替换为任意类 class SomeSchema { public hello: string; constructor(hello: string) { this.hello = hello; } sayHello() { console.log('hello', this.hello); } } const createSomeSchemaRepo = createRepository(SomeSchema); const someRepo: Repository<SomeSchema> = createSomeSchemaRepo();
当前收到的错误提示:
TS2322: Type 'Repository
' is not assignable to type 'Repository '. Type 'typeof SomeSchema' is missing the following properties from type 'SomeSchema': hello, sayHello
解决方案
问题根源在于,原代码中泛型T被TypeScript推断为类的构造函数类型(即typeof SomeSchema),而非我们期望的类的实例类型。要修正这个问题,需要将工厂函数的参数类型约束为「能构造出T实例的构造函数」:
修改createRepository的定义如下:
export const createRepository = <T>(schema: new (...args: any[]) => T) => // 约束schema为返回T实例的构造函数 (): Repository<T> => ({ async add(data) { // 业务逻辑 }, });
原理说明
new (...args: any[]) => T是TypeScript中的构造函数类型签名,表示该参数是一个可以通过new关键字创建出T类型实例的类。- 此时传入
SomeSchema时,TypeScript会自动将T推断为SomeSchema的实例类型,而非构造函数类型,最终返回的工厂函数会生成Repository<SomeSchema>类型的实例,完全符合预期。
内容的提问来源于stack exchange,提问作者Marcus Ruddick
相关产品推荐
相关产品推荐

