如何在泛型类中创建T类型对象?有无可行方案?
在TypeScript泛型类中创建T类型对象的方法
TypeScript里直接在泛型类里用new T()会报错,核心原因是泛型类型T仅存在于编译阶段,编译后会被完全擦除,运行时根本没有T这个值,所以无法直接通过类型标识创建实例。下面是几种可行的变通方案:
方案1:传入T的构造函数
让调用者提供T对应的构造函数,作为类的初始化参数,通过这个构造函数来创建实例:
type Foo = { /*...*/ }; class Bar<T extends Foo> { public readonly foo: T; public constructor( init?: { foo: T }, // 接收T的无参构造函数类型 private readonly TConstructor: new () => T ) { this.foo = init?.foo ?? new this.TConstructor(); } }; // 使用示例:传入具体的构造函数 class ConcreteFoo implements Foo { /* 实现Foo的结构 */ } const bar = new Bar(undefined, ConcreteFoo);
如果T的构造函数需要参数,可以调整构造器类型,比如new (arg1: Type1) => T,调用时传入对应参数即可。
方案2:设置默认构造函数(针对有默认实现的场景)
如果T有默认的实现类,可以给泛型设置默认类型,同时提供默认的构造函数参数,简化调用:
type Foo = { /*...*/ }; // 默认实现Foo的类 class DefaultFoo implements Foo { /*...*/ } class Bar<T extends Foo = DefaultFoo> { public readonly foo: T; public constructor( init?: { foo: T }, // 给构造函数参数设置默认值 private readonly TConstructor: new () => T = DefaultFoo as new () => T ) { this.foo = init?.foo ?? new this.TConstructor(); } }; // 使用示例:无需传构造函数,直接使用默认实现 const bar = new Bar(); // 也可以传入自定义构造函数 const customBar = new Bar(undefined, ConcreteFoo);
方案3:使用工厂函数(更灵活的场景)
如果T是接口或者不需要通过类构造函数创建的类型,可以传入一个工厂函数来生成实例,这种方式比构造函数更灵活:
type Foo = { id: number; name: string }; class Bar<T extends Foo> { public readonly foo: T; public constructor( init?: { foo: T }, // 接收返回T的工厂函数 private readonly factory: () => T ) { this.foo = init?.foo ?? this.factory(); } }; // 使用示例:传入工厂函数生成符合Foo的对象 const bar = new Bar(undefined, () => ({ id: 1, name: "test" } as T));
内容的提问来源于stack exchange,提问作者PatrykB
相关产品推荐
相关产品推荐

