在typescript的基类构造函数参数中引用子类的实例类型

在typescript的基类构造函数参数中引用子类的实例类型,typescript,Typescript,我正在Typescript 3.4.2和Node v.12中开发事件源原型 它工作得很好,但我希望避免为每种类型的事件编写复制粘贴的构造函数和泛型,如AbstractEvent 有没有办法基于子类实例在父类构造函数中启用TS类型检查 抽象类AbstractEvent{ //我想在这里输入系统,比如: //公共构造函数(数据:InstanceType) 公共构造函数(数据:任意){ for(常量输入数据){ 此[键]=数据[键]; } } } 类PackCreateEvent扩展了Abstract

我正在Typescript 3.4.2和Node v.12中开发事件源原型

它工作得很好,但我希望避免为每种类型的事件编写复制粘贴的构造函数和泛型,如
AbstractEvent

有没有办法基于子类实例在父类构造函数中启用TS类型检查

抽象类AbstractEvent{
//我想在这里输入系统,比如:
//公共构造函数(数据:InstanceType)
公共构造函数(数据:任意){
for(常量输入数据){
此[键]=数据[键];
}
}
}
类PackCreateEvent扩展了AbstractEvent{
公共只读id:string;
公共只读标题:字符串;
//我希望避免为每种事件类型编写构造函数
//同时也尽量避免额外的接口
公共构造函数(数据:PackCreatedEvent){
超级(数据);
}
}
类UserCreatedEvent扩展了AbstractEvent{
公共只读id:string;
公共只读电子邮件:字符串;
}
//实例化
const packCreatedEvent1=新PackCreatedEvent({
id:'GSNV-FGHT-FGHF-HFTH',
标题:"苹果",,
});
const packCreatedEvent2=新PackCreatedEvent({
id:'ABGF-FGHT-FGHF-HFTH',
标题:"香蕉",,
//取消注释以查看错误
//someBadProperty:“测试”,
});
const userCreatedEvent=new userCreatedEvent({
id:'GSNV-FGHT-FGHF-HFTH',
电邮:'test@mail.com',
//不是有效的属性
//而不是因为AbstractEvent.constructor中的“any”而出错
someBadProperty:“测试”,
});

构造函数中没有访问派生类的内置方法。多态
正如注释中所指出的,此
在构造函数中不可访问

最简单的选择是将类型参数添加到
AbstractEvent
。类型参数将是派生类中的类本身。这种解决方案的优点是不需要任何额外的运行时代码。不需要派生类型构造函数

abstract class AbstractEvent<T extends AbstractEvent<any>> {
    public constructor(data: T) {
        for (const key in data) {
            this[key as any] = data[key];
        }
    }
}

class PackCreatedEvent extends AbstractEvent<PackCreatedEvent> {
    public readonly id: string;
    public readonly title: string;
}

class UserCreatedEvent extends AbstractEvent<UserCreatedEvent> {
    public readonly id: string;
    public readonly email: string;
}

const userCreatedEvent = new UserCreatedEvent({
    id: 'GSNV-FGHT-FGHF-HFTH',
    email: 'test@mail.com',

    // not a valid property
    // error now
    someBadProperty: 'test',
});
抽象类AbstractEvent{
公共构造函数(数据:T){
for(常量输入数据){
此[key as any]=数据[key];
}
}
}
类PackCreateEvent扩展了AbstractEvent{
公共只读id:string;
公共只读标题:字符串;
}
类UserCreatedEvent扩展了AbstractEvent{
公共只读id:string;
公共只读电子邮件:字符串;
}
const userCreatedEvent=new userCreatedEvent({
id:'GSNV-FGHT-FGHF-HFTH',
电邮:'test@mail.com',
//不是有效的属性
//现在出错
someBadProperty:“测试”,
});

非常有趣的问题。我想说的是,您可以只使用
data:AbstractEvent
,但是您的
packCreatedEvent2
即使在未注释行的情况下也可以工作。我想要
data:typeof this
data:this
(尝试那样做),但是那些不起作用,我尝试了它们。:-)@T.J.Crowder认为没有OP想要的解决方案。我不知道如何从基类型访问派生类型(正如您所指出的,多态
这个
在构造函数中不可用)。我能想到的唯一替代解决方案是使用静态方法,而不是使用
new
(使用静态方法,我们可以提取目标类),或者使
AbstractEvent
泛型并传入派生类
class PackCreatedEvent extensed AbstractEvent{..}
,我认为这是最简单的选择。如果Infloop能够澄清他反对泛型的原因,也许我们可以解决一些问题。@TitianCernicova Dragomir-感谢您的关注!看看这是怎么回事会很有趣的。您的通用方法看起来确实很简单——不需要显式地创建构造函数,只需将
添加到
扩展
@TitianCernicova Dragomir-我想我们必须伪造
这个[key]=data[key]
部分(
(这个就是任何的)[key]=data[key];
),但这似乎是可以接受的(也是不可避免的)。除此之外,.Infloop,type参数至少不是运行时代码:)@T.J.Crowder您想写它还是我应该写?