2016-03-15 65 views
0

Structural Subtyping打字稿對象類型相比,結構上

對象類型結構比較。例如,在下面的代碼 片段中,'CPoint'類匹配'Point'接口,因爲 'CPoint'具有'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 I型可以在任何地方我可以一個Point傳遞它。如果Point聲明所有實現者都有方法Foo(x:string)CPoint將不具有該方法。因此,如果CPoint被傳入,任何接受Point並希望使用Foo的人都會炸燬。

我的問題是,我是否解釋了這個錯誤,如果不是,爲什麼這被認爲足以放入語言規範?

回答

2

如果Point指出所有的實現者都有方法Foo(x:string),那麼CPoint就沒有這個方法。因此,任何接受Point並希望使用Foo的人都會在CPoint被傳入之後爆發。

如果你這樣做了,你會得到一個編譯時錯誤,CPoint缺少Foo方法。我建議在TypeScript Playground上嘗試它。

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