我试图在TypeScript中实现工厂模式,但我无法访问超类中不存在的子函数。 (它有效,但编译器给我一个错误。)
结构:
abstract class Animal {
walk(meters:number) { ... }
}
class Elephant extends Animal {
walk(meters:number) { ... }
}
class Eagle extends Animal {
walk(meters:number) { ... }
fly(meters:number) { ... }
}
我的工厂:
class Zoo {
animals:Animal[] = [];
addAnimal(type:string): Animal {
var a: Animal;
switch(type) {
case 'elephant':
a = new Elephant();
break;
case 'eagle':
a = new Eagle();
break;
default:
throw new Error('Animal of type \'' + type + '\' doesn\t exist');
}
this.animals.push(a);
return a;
}
}
然后:
var sammy:Animal = addAnimal('eagle');
sammy.fly(15);
这给了我: 错误:TS2339:'Animal'类型中不存在属性'fly'。
我也试图施展:
var sammy:Eagle = addAnimal('eagle');
sammy.fly(15)
这给了我: 错误:TS2322:类型'Animal'不能分配给'Eagle'类型。 “动物”类型中缺少属性“fly”。
我在TypeScript页面上创建了一个代码操场:http://bit.ly/21yXXjf
答案 0 :(得分:2)
您可以使用类型断言将类型检查从TypeScript中取出并自行掌握。
var sammy = <Eagle><any>zoo.addAnimal('eagle');
sammy.fly(15)
这可能会导致问题,因此可以更好地解决您的问题(以及一般的工厂问题)......
使用专门的签名根据静态字符串返回正确的类型:
class Zoo {
animals:Animal[] = [];
addAnimal(type: 'elephant'): Elephant;
addAnimal(type: 'eagle'): Eagle;
addAnimal(type: string): Animal;
addAnimal(type: string): Animal {
var a: Animal;
switch(type) {
case 'elephant':
a = new Elephant();
break;
case 'eagle':
a = new Eagle();
break;
default:
throw new Error('Animal of type \'' + type + '\' doesn\t exist');
}
this.animals.push(a);
return a;
}
}
var zoo = new Zoo();
// No type assertion needed, sammy is an eagle!
var sammy = zoo.addAnimal('eagle');
sammy.fly(15)
答案 1 :(得分:0)
您正在返回一个类型为Animal的动物,然后尝试访问此类型中不存在的属性“fly”,可能的解决方案是将属性“fly”添加到Animal类,或者从addAnimal方法中删除Animal类型{ {1}},或者您可以将代码更改为:
addAnimal(type:string): Animal {}
只需将var sammy = <Eagle>myZoo.addAnimal('eagle'); // This woudl work without errors!
类型添加到方法调用