接口类型的数组(带接口的多态)

时间:2016-04-24 10:46:22

标签: typescript polymorphism typescript1.8

我正在尝试创建一个对象数组,其中所有对象都实现了接口Foo。以下是演示此问题的简化示例:

interface Foo {
    fooAction(): any;
}

class Bar implements Foo
{
     public fooAction() {
          return "nothing important";
      }
 }

 let arrayThatINeed : Foo[] = [Bar]; // Type error: Type Bar[] is not 
                                     // assigable to type 'Foo[]'

不应支持此行为吗?如果没有,那么对这种行为进行编码的替代方案是什么?

2 个答案:

答案 0 :(得分:3)

您正在将类添加到数组而不是该类的实例 应该是:

let arrayThatINeed : Foo[] = [new Bar()];

这也有效:

let arrayThatINeed : Foo[] = [{
    fooAction: () => { console.log("yo"); }
}];

修改

我不是一个有角度的开发人员,所以我无法与之相关,但如果我理解正确,那么你需要一个类而不是实例的数组,这在javascript中意味着你需要一个构造函数数组。

这在打字稿中很容易做到:

interface FooConstructor {
    new (): Foo;
}

interface Foo {
    fooAction(): any;
}

class Bar implements Foo {
    public fooAction() {
        return "nothing important";
    }
}

let arrayThatINeed : FooConstructor[] = [Bar];

您会看到此代码不会导致错误,但它也不正确,因为即使您从implements类中删除Bar部分也不会抱怨。<登记/> 我可以找到原因,但我认为编译器应该抱怨它。

如果你让Foo成为一个类,你可以解决这个问题,例如:

interface FooConstructor {
    new (): Foo;
}

abstract class Foo {
    abstract fooAction(): any;
    fn() {}
}

class Bar extends Foo {
    public fooAction() {
        return "nothing important";
    }
}

let arrayThatINeed : FooConstructor[] = [Bar];

现在,如果您从extends移除Bar部分,则会收到错误 但是你必须在Foo中至少有一个非抽象方法/成员才能工作(也就是说,如果数组中的内容不是扩展Foo的类,它会抱怨。)

答案 1 :(得分:2)

如果您希望数组项满足var menu = require('./menu-partial'); it('should go to tutorial', function() { menu.dropdown('Quick Start').item('Tutorial'); expect($('h1').getText()).toBe('Tutorial'); }); 接口,则项需要满足具有Foo[]属性的对象(即方法Foo)。在实例化fooAction的实例之前,它不满足接口。

Bar

如果您希望数组包含var barInstance = new Bar(); let items: Foo[] = [ barInstance ]; 类型,而不是实例化类,则可以创建一个表示该类型的类型 - 如果您将Foo作为抽象类。

Foo