假设这段代码:
class Module{
contructor(){
// some logic here
}
}
class LoginModule extends Module{
start(){}
}
class Server{
modules: Module[];
constructor(modules?: Array<{new():Module}>){
for(var moduleConstructor of modules){
var module = new moduleConstructor();
this.modules.push(module);
}
}
}
var server = new Server([LoginModule]);
var loginModule:LoginModule = server.modules[0];
为什么我收到错误:
类型'模块'不能分配给'LoginModule'类型。 “模块”类型中缺少属性“start”。
我需要从Module
扩展类的对象数组,然后我想使用typescript来识别对象类型。
我可以改变
var loginModule:LoginModule = server.modules[0];
到
var loginModule:Module = server.modules[0];
但是我会在IDE中丢失intellisense提示。
答案 0 :(得分:1)
财产modules
的定义是
class Server{
modules: Module[]; // type is not LoginModule, just Module
...
所以,肯定不是LoginModule。但是,如果我们知道实例是LoginModule,我们可以使用带有断言 (as
语句)的赋值:
//var loginModule:LoginModule = server.modules[0];
var loginModule = server.modules[0] as LoginModule;
现在,loginModule变量被视为LoginModule
实例...
答案 1 :(得分:0)
如果Server
需要LoginModule
,请通过要求LoginModule
明确要求:
class Module{
contructor(){
// some logic here
}
}
class LoginModule extends Module{
start(){}
}
class Server{
modules: Module[];
constructor(public loginModule: LoginModule, modules?: Array<{new():Module}>){
for(var moduleConstructor of modules){
var module = new moduleConstructor();
this.modules.push(module);
}
}
}
var server = new Server(new LoginModule, [LoginModule]);
var loginModule:LoginModule = server.loginModule;
类型系统现在会将您保存为消费者和提供者,因为如果您尝试传递其他类型的Module
,它会警告您。你也可以找回预期的类型。
您仍然可以提供不同的LoginModule
类型,只要它们在结构上完全相同。
我怀疑你不希望每个模块都可以交换,而是希望某些类型的模块可以交换 - 所以在构造函数中允许每种类型中的一个或多个(我想你是从类似于Express中间件的东西,你可以允许用户为某些类型的事件指定一些处理程序。)