typescript对象类型在结构上进行比较

时间:2016-03-15 20:49:59

标签: typescript

Structural Subtyping

  

对象类型在结构上进行比较。例如,在代码中   下面的片段,类' CPoint'匹配界面' Point'因为   '连接点'拥有所有必需的“Point'成员”。一堂课可以   可选地声明它实现了一个接口,以便   编译器将检查声明的结构兼容性。该   示例还说明对象类型可以匹配该类型   从对象文字推断,只要对象文字   提供所有必需的成员。

 interface Point {  
     x: number;  
     y: number;   }

 function getX(p: Point) {  
     return p.x;   }

 class CPoint {  
     x: number;  
     y: number;  
     constructor(x: number,  y: number) {  
         this.x = x;  
         this.y = y;  
     }   }

 getX(new CPoint(0, 0));  // Ok, fields match

 getX({ x: 0, y: 0, color: "red" });  // Extra fields Ok

 getX({ x: 0 });  // Error: supplied parameter does not match

在他们的示例中,CPoint被认为是Point类型,因为它是Point类型,我可以将它传递给Point。如果Point声明所有实施者都使用方法Foo(x:string),则CPoint将不具备该方法。因此,如果Point被传递到Foo,那么接受CPoint并期望使用{{1}}的任何人都会爆炸。

我的问题是,我是否解释了这个错误,如果不是为什么这被认为是一个足够好的语言规范?

2 个答案:

答案 0 :(得分:2)

  

如果Point声明所有实现者都有方法Foo(x:string),那么CPoint就不会有这种方法。因此,如果将CPoint传递给它,任何接受Point并期望使用Foo的人都会爆炸。

如果您这样做,您将收到CPoint缺少Foo方法的编译时错误。我建议在TypeScript Playground上试一试。

答案 1 :(得分:1)

创建的类型定义/接口只是编译时的事情,在我看来,结构子类型是一个很好的特性。

如果使用其他方法Point扩展Foo(x: string)接口,则告诉编译器现在每个想要成为Point的对象也需要此方法。在我看来,这正是你想要的,因为你可以找到你传递缺少这些附加属性的对象的所有地方。

在将这样的方法添加到界面之前,如果每个具有Point特征的对象确实需要这种方法,那么问问自己可能会更好。根据我的经验,通常更好地引入一些更多的接口,例如Fooable并使用此处,您需要一个需要Foo方法的对象。

如果你的方法确实需要具有两个特征的对象,(x,y)和Foo,你可以这样做:

function myMethodRequiringASpecialObject(x: Point & Fooable) {}

这被称为"交叉类型"。点击此处:https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html