2014-01-08 39 views
2
export class Base { 
    static getSomething():typeof this //<-- change this? 
    { 
     var type = typeof this; 
     return new this['type'](); 
    } 
} 
export class Foo extends Base { 
    publicVar:string = 'getThis!'; 
} 

var foo:Foo = Foo.getSomething(); 
var success:string = foo.publicVar; 

上面的返回錯誤是因爲編譯器說Foo.getSomething會返回一個Base而不是Foo。 我想知道是否有另一種方式讓我調用編譯器知道的Foo的靜態函數將返回Foo。是否有可能在打字稿中有函數返回延伸它的類的類型

Ofcourse我可以明確地Foo中的每一個擴展的基類實現它,因此,我也可以簡單地強制轉換它:

var foo:Foo = <Foo> Foo.getSomething(); 

但我不知道是否有無需做任何一種方式這些事情,因爲我將使用這種方法很多

回答

4

擺脫的類型斷言

如果按照里氏替換原則,你並不需要的類型的斷言。

代碼示例1 - 可替代性對象...

module Test { 
    export class Base { 
     publicVar: string = 'base'; 

     static getSomething() : Base { 
      //... read on... 
     } 
    } 

    export class Foo extends Base { 
     publicVar:string = 'getThis!'; 
    } 
} 

// No <Foo> type assertion needed 
var foo: Test.Foo = Test.Foo.getSomething(); 

alert(foo.publicVar); 

或者,你可以創建一個interface告訴你返回將有一個publicVar屬性,並返回該對象...

代碼示例2 - 接口

module Test { 
    export interface IPublicVarable { 
     publicVar: string; 
    } 

    export class Base { 
     static getSomething() : IPublicVarable { 
      //... read on... 
     } 
    } 

    export class Foo extends Base { 
     publicVar:string = 'getThis!'; 
    } 
} 

// No <Foo> type assertion needed 
var foo: Test.IPublicVarable = Test.Foo.getSomething(); 

alert(foo.publicVar); 

獲取實際類型

這並不能解決你遇到的其他問題 - var type = typeof this;不會在運行時給你所期望的。它會給你Function而不是Foo

爲了得到一個類型的名字,你真的需要一個實例來工作(如果你使用Test.Foo該類型名稱是Function再一次 - 這對你沒有好),所以這裏使用兩個不同的子類,這兩個不完美的例子滿足界面,基於我Obtaining a Class Name at Runtime example

module Test { 
    export class Describer { 
     static getName(inputClass) { 
      var funcNameRegex = /function (.{1,})\(/; 
      var results = (funcNameRegex).exec((<any> inputClass).constructor.toString()); 
      return (results && results.length > 1) ? results[1] : ""; 
     } 

     static getInstanceOf(inputClass) : Test.IPublicVarable { 
      var name = Describer.getName(inputClass); 
      return new Test[name](); 
     } 
    } 

    export interface IPublicVarable { 
     publicVar: string; 
    } 

    export class Base { 

    } 

    export class Foo extends Base { 
     publicVar:string = 'foo class'; 
    } 

    export class Bar extends Base { 
     publicVar:string = 'bar class'; 
    } 
} 

var a: Test.Base = new Test.Foo(); 
var x: Test.IPublicVarable = Test.Describer.getInstanceOf(a); 
alert(x.publicVar); 

var b: Test.Base = new Test.Bar(); 
var y: Test.IPublicVarable = Test.Describer.getInstanceOf(b); 
alert(y.publicVar); 
相關問題