TypeScript接口和实现

时间:2014-12-11 18:34:20

标签: typescript

我正在玩TypeScript和接口。我有以下代码

interface Control {
    name: string;
    onSelect():string;
}

class Button {
    name:string="button";
    onSelect = function() {
        return "hello";
    }
}

var a:Button = new Button();
var b:Control = {"name": "arbitrary", "onSelect": () => { return "ahoy!"; }};

var trigger = function(c:Button) {
    console.log(c.name, "says", c.onSelect());
}

trigger(a);
trigger(b);

编译并运行而不抱怨。任何人都可以解释为什么我的trigger函数接受b,即使它希望获得Button类型而b类型为Control

即使Button要明确实施Control,我也要求Button而不是Control。出于所有预期目的,Button可能包含其他成员。

TypeScript是否因为它们在结构上相同而推断实现?你是否可以通过一个预期实现类的接口? (不应该是相反的方式吗?)

2 个答案:

答案 0 :(得分:4)

TypeScript documentation on interfaces

中所述
  

TypeScript的核心原则之一是类型检查侧重于值所具有的“形状”。这有时被称为“鸭子打字”

"duck typing"中:

  

如果它看起来像鸭子,像鸭子一样游泳,那么它很可能是鸭子。

换句话说,TypeScript检查提供的对象或类型的形状(方法和属性)。如果提供的对象包含接口描述的所有属性和方法,则该对象很可能被视为与所描述的接口兼容的对象。

在您的示例中,您的界面和类看起来完全相同,因此TypeScript会将您的对象视为与所描述的界面兼容。

如果您examine the generated JavaScript,请注意根本没有提及您的界面 - 这是因为TypeScript接口本质上是开发人员提供的类型元数据,可帮助TypeScript验证类型兼容性。

答案 1 :(得分:1)

interfaceclass都具有相同的实现,因此在期望Button时,您传入兼容对象(具有返回字符串的名称和返回a的onSelect函数)字符串)

如果您将另一个属性添加到Button,例如greeting: string,则trigger(b)上的错误会导致其无效。

interface Control {
    name: string;
    onSelect:() => string; // this is another way to write function that returns a string
}

class Button implements Control {
    name:string="button";
    onSelect = function() {
        return "hello";
    }
    greeting: string; // adding this will cause trigger(b) to fail
}