2014-03-13 37 views
0

請參閱代碼here它在打字稿中,但是由於與C#的相似性,它可能也適用於它。靜態打印和通用反轉

export class Promise<T> { 
} 
export interface IId{ 
    id:()=> string; 
} 
class Service { 
    get(id:string): Promise<IId> { return } 
} 

export interface IUser extends IId{ 
    name: string 
} 

export interface IUserService{ 
    test:(d:string) => Promise<IUser>; 
} 

class UserService implements IUserService{ 

    constructor(private srv: Service){} 

    test(d:string):Promise<IUser> { 
     return this.srv.get(""); 
    } 
} 

說,我有一個框架,服務功能get返回IId類型的承諾。在我的自定義類中,我有一個方法,它被定義爲返回IUser類型的承諾。我通過返回this.srv.get("")錯誤,返回Promise<IId>。但是這不應該與Promise<IUser>兼容,因爲IUser期望name字段。爲什麼沒有錯誤?我不熟悉C#泛型,這是什麼叫contravariance。閱讀一些文章,但無法包裹我的頭。

+0

與C#的相似之處在於它們都使用大括號? – AakashM

+0

不,它來自MS並受同一設計師的影響。另外,在討論板和所有的許多內容中都提到了C#。它也完全支持Visual Studio,並且可以作爲C#的客戶端語言對象。 – bsr

+1

雖然Anders曾在C#和TypeScript上工作​​過,但他也曾在Delphi和Turbo Pascal上工作過。儘量不要讀得太多。 –

回答

2

您的Promise類型爲空不使用T,這兩者都是非常大的問題。 TypeScript使用結構類型系統,因此空類型是所有類型的超類型,而不使用類型參數的泛型類型實際上不會對這些類型參數進行類型檢查。

如果Promise使用它的類型參數,你會看到一個錯誤:

export class Promise<T> { 
    foo: T; // <- ADDED 
} 
export interface IId{ 
    id:()=> string; 
} 
class Service { 
    get(id:string): Promise<IId> { return } 
} 

export interface IUser extends IId{ 
    name: string 
} 

export interface IUserService{ 
    test:(d:string) => Promise<IUser>; 
} 

class UserService implements IUserService{ 

    constructor(private srv: Service){} 

    test(d:string):Promise<IUser> { 
     // ERROR 
     return this.srv.get(""); 
    } 
} 

嘗試使用C#(標稱類型系統)作爲參考點爲打字稿(結構類型系統)是不會非常有成效。