class - 创建其类型变量类的实例的 TypeScript 泛型类?
问题描述
我熟悉 TypeScript 中的泛型类,其中可以使用关联的类型变量定义一个类,然后具有特定类型的实例可以操作并返回该类型的值。
问题:我想要一个创建类型变量实例的泛型类。例如:
class Thing {
thingProp: string;
}
class ThingOne extends Thing {
thingOneProp: string;
}
class ThingTwo extends Thing {
thingTwoProp: string;
}
class Maker<T extends Thing> {
make(): T {
return new T();
// ^--- " // <- "error TS2304: Cannot find name 'T'""
}
}
let thingOneMaker = new Maker<ThingOne>();
let thingOne: ThingOne = thingOneMaker.make();
let thingTwoMaker = new Maker<ThingTwo>();
let thingTwo: ThingTwo = thingTwoMaker.make();
let thingError: ThingOne = thingTwoMaker.make();
// ^--- "error TS2322: Type 'ThingTwo' is not assignable to type 'ThingOne'"
这几乎似乎有效。编译器生成代码,最后一行的错误表明 TypeScript 理解thingTwoMaker.make()
应该返回什么类型。
但是,错误return new T();
表明 TypeScript 不理解我正在尝试创建类型变量类的实例,并且生成的 JavaScript 确认了这一点:
var Maker = (function () {
function Maker() {
}
Maker.prototype.make = function () {
return new T(); // <- "error TS2304: Cannot find name 'T'"
};
return Maker;
}());
而且,毫不奇怪,使用 Node.js 运行生成的 JavaScript 会产生ReferenceError: T is not defined
错误。
如何创建一个泛型类,其实例可以创建类型变量类的实例?(使用 TypeScript 2.0.10 测试。)
解决方案
不知何故,您需要为Maker
类提供您希望它创建的类型的构造函数,以便它具有可以调用的值new
。
我想说一个不错的选择是将类构造函数作为参数传递给Maker
's 的构造函数。这将允许它构造该类的实例,并且它会自动推断它正在构建的类型,因此您不必再手动注释泛型类型。
所以也许是这样的:
class Maker<T extends Thing> {
private ctor: {new(): T};
constructor(ctor: {new(): T}) {
this.ctor = ctor;
}
make(): T {
return new this.ctor();
}
}
然后,您可以将正确的类构造函数传递给每种类型Maker
,类型将被自动推断:
let thingOneMaker = new Maker(ThingOne);
let thingOne: ThingOne = thingOneMaker.make();
let thingTwoMaker = new Maker(ThingTwo);
let thingTwo: ThingTwo = thingTwoMaker.make();
// Still an error.
let thingError: ThingOne = thingTwoMaker.make();
推荐阅读
- ios - 真iPhone XR屏幕分辨率和swift给出的屏幕分辨率不一样?
- php - 表单提交后重定向在 IE 中不起作用,但在 chrome 中起作用
- html - Vuetify.js - 为 v-card 添加模糊和透明样式
- docker - Docker Container 中 ASP.NET Core appsettings.json 的路径
- python - Python 2.7.1 ValueError:解包的值太多
- css - 如何在仍然响应的 boostrap 4 导航栏中制作重叠的徽标图像?
- netsuite - 我可以在 Netsuite 中的装配物料清单打印中添加列吗?
- javascript - 是否可以在 Android 设备上延迟 PWA 横幅“添加到主屏幕”?
- google-chrome - Chrome 未通过 console.log 显示控制台消息
- spring-tool-suite - STS 4 中不包含 Pivotal tc 服务器