TypeScript工厂模式表示属性不存在

时间:2016-03-18 11:28:03

标签: javascript inheritance typescript abstract-class factory-pattern

我试图在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

2 个答案:

答案 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!类型添加到方法调用

即可