对象类型在结构上进行比较。例如,在代码中 下面的片段,类' 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}}的任何人都会爆炸。
我的问题是,我是否解释了这个错误,如果不是为什么这被认为是一个足够好的语言规范?
答案 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