Typescript不允许使用不同构造函数签名的类的继承类型

时间:2015-10-30 18:30:03

标签: inheritance static compiler-errors typescript

我正在实现一个commandBus,我想用命令处理程序注册命令类型,以将传入的命令映射到正确的命令处理程序。我传递了一个命令构造函数来映射到像register(handler : typeof Handler, command : typeof Command)这样的处理程序构造函数。但我一直在犯compilaton错误。

我终于找到了原因。在typescript中,您无法定义参数arg typeof X并传入构造函数Y,如果是Y extends X则传递。 构造函数必须具有相同的签名

检查该代码段。在底部,即使commandBus.register(Object)也不会抛出编译错误。

class BaseClass{}
class DerivedClass extends BaseClass{
    constructor(b : number) {
        super();
    }
}
class AnotherClass extends BaseClass{
    constructor(){
        super();
    }
}
class CommandBus {
    register(handler : typeof BaseClass) {}
}
var commandBus = new CommandBus();
commandBus.register(DerivedClass); // Argument of type 'typeof DerivedClass' is not assignable to parameter of type 'typeof BaseClass'.
commandBus.register(AnotherClass); // Compiles
commandBus.register(Function); // Compiles
commandBus.register(Object); // Compiles

我使用它的唯一方法是添加一个重载构造函数签名

class DerivedClass extends BaseClass{
    constructor(b? : any);
    constructor(b : number) {
        super();
    }
}

但是我或者这是该死的吗?

任何人都可以指出我如何摆脱这些编译器错误的方向,而不是在整个地方添加无用的过载签名的肮脏黑客?

1 个答案:

答案 0 :(得分:3)

你在这里真正要说的是你想要一个带有任意数量参数的BaseClass的构造函数。你可以写这种类型:

class CommandBus {
    register(handler: new(...args: any[]) => BaseClass) {}
}

请注意,错误是100%正确的。如果你写了

class CommandBus {
    register(handler : typeof BaseClass) {
       var x = new handler();
    }
}
var c = new CommandBus();
c.register(DerivedClass);

您将零参数传递给DerivedClass构造函数。

这些行在这里

commandBus.register(Function); // Compiles
commandBus.register(Object); // Compiles

只编译,因为BaseClass没有成员(请记住,TypeScript使用结构类型系统,因此空类型可以从任何类型分配!)。如果您向BaseClassFunction中的Object添加任何属性或方法,则这些行会出错。