TypeScript 工厂模式说 属性 不存在
TypeScript factory pattern says property doesnt exist
我试图在 TypeScript 中实现工厂模式,但我无法访问超级 class 中不存在的子函数。 (它有效,但编译器给我一个错误)。
结构:
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:属性 'fly' 在类型 'Animal' 上不存在。
我也尝试投射:
var sammy:Eagle = addAnimal('eagle');
sammy.fly(15)
这给了我:
错误:TS2322:类型 'Animal' 不可分配给类型 'Eagle'。
属性 'fly' 在类型 'Animal' 中缺失。
我在 TypeScript 页面上做了一个代码游乐场:http://bit.ly/21yXXjf
快速修复
您可以使用类型断言将类型检查从 TypeScript 转移到您自己手中。
var sammy = <Eagle><any>zoo.addAnimal('eagle');
sammy.fly(15)
这可能会导致问题,因此有更好的解决方案来解决您的问题(以及一般的工厂问题)...
更好的解决方案
使用专门的签名 return 基于静态字符串的正确类型:
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)
您正在返回类型为 Animal 的动物,然后尝试访问 属性 'fly',此类型不存在,可能的解决方案是添加 属性 'fly' 到 Animal class,或从 addAnimal 方法 addAnimal(type:string): Animal {}
中删除 Animal 类型,或者您可以将代码更改为:
var sammy = <Eagle>myZoo.addAnimal('eagle'); // This woudl work without errors!
只需将 <Eagle>
类型添加到您的方法调用
我试图在 TypeScript 中实现工厂模式,但我无法访问超级 class 中不存在的子函数。 (它有效,但编译器给我一个错误)。
结构:
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:属性 'fly' 在类型 'Animal' 上不存在。
我也尝试投射:
var sammy:Eagle = addAnimal('eagle');
sammy.fly(15)
这给了我: 错误:TS2322:类型 'Animal' 不可分配给类型 'Eagle'。 属性 'fly' 在类型 'Animal' 中缺失。
我在 TypeScript 页面上做了一个代码游乐场:http://bit.ly/21yXXjf
快速修复
您可以使用类型断言将类型检查从 TypeScript 转移到您自己手中。
var sammy = <Eagle><any>zoo.addAnimal('eagle');
sammy.fly(15)
这可能会导致问题,因此有更好的解决方案来解决您的问题(以及一般的工厂问题)...
更好的解决方案
使用专门的签名 return 基于静态字符串的正确类型:
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)
您正在返回类型为 Animal 的动物,然后尝试访问 属性 'fly',此类型不存在,可能的解决方案是添加 属性 'fly' 到 Animal class,或从 addAnimal 方法 addAnimal(type:string): Animal {}
中删除 Animal 类型,或者您可以将代码更改为:
var sammy = <Eagle>myZoo.addAnimal('eagle'); // This woudl work without errors!
只需将 <Eagle>
类型添加到您的方法调用