TypeScript泛型类型参数实例化报错:‘T仅为类型却被用作值’
TypeScript泛型中
new T()编译错误的原因及解决方法 先看给出的代码片段:
class TBase { } class Foo<T extends TBase> { f() :T { return new T(); } }
这段代码里new T()会触发编译错误:
'T' only refers to a type, but is being used as a value here.
核心原因
TypeScript的泛型参数T是类型层面的标识,只在编译阶段有效,编译成JavaScript后,泛型类型会被完全擦除——运行时根本不存在T这个值,自然无法用它来实例化对象。这里混淆了「类型」和「值」的边界:T是类型,而能被new的必须是具体的构造函数(属于值的范畴)。
解决方法
要实现通过泛型创建实例,需要让代码能拿到T对应的构造函数(值),同时通过泛型约束限定构造函数的签名。
方法1:通过类的构造函数传入类型
class TBase { } class Foo<T extends TBase> { // 接收T的构造函数作为参数,构造签名`new () => T`表示无参构造返回T实例 constructor(private readonly typeConstructor: new () => T) {} f(): T { return new this.typeConstructor(); } } // 使用示例 const foo = new Foo(TBase); const instance = foo.f();
方法2:在方法中直接传入构造函数
class TBase { } class Foo<T extends TBase> { f(typeConstructor: new () => T): T { return new typeConstructor(); } } // 使用示例 const foo = new Foo<TBase>(); const instance = foo.f(TBase);
补充说明
如果TBase的子类需要带参数的构造函数,只需调整构造签名即可,比如new (name: string) => T,这样就能支持带参数的实例化。
内容的提问来源于stack exchange,提问作者Seva Alekseyev
相关产品推荐
相关产品推荐

