2014-06-28 230 views
6

意思是你不能用這樣的東西?Typescript泛型是否使用類型擦除來實現泛型?

class Helpers 
{ 
    static ObjectAs<T>(val: any): T { 
     if (!(val instanceof T)) { 
      return null; 
     } 

     return <T>val; 
    } 
} 

任何解決方法來獲取泛型聲明的基礎類型?

更新1:

萊恩卡瓦諾提到的,在編譯時,整個系統類型被擦除,更像是Java的泛型實現的。我相信.Generics的Net實現在編譯代碼中保留類型信息比Java更好。 但是,我忍不住想知道,爲什麼不能在TypeScript中允許對泛型類型和泛型類型參數進行完整的運行時自檢?爲什麼TypeScript的設計者決定在運行時刪除所有通用類型信息?

以下打字稿代碼:

function As<T>(n: any): T { 
    if (n instanceof T) { 
     return n; 
    } else { 
     return null; 
    } 
} 

var obj: Object = 1; 
var x = As<number>(obj); 

可以轉換爲這段JavaScript代碼:

function As(n, T) { 
    if (n instanceof T) { 
     return n; 
    } else { 
     return null; 
    } 
} 

var obj = 1; 
var x = As(obj, Number); 

保留在運行,並與JS代碼兼容性類型的信息!

更新2: 我已經張貼在CodePlex上的問題,希望能得到更多的從打字稿人 https://typescript.codeplex.com/discussions/550262

+0

多麼真棒問題...希望它並不封閉,從而風格 –

+1

第2頁的JavaScript是由編譯器發射前的所有類型的信息將被刪除的規範狀態。鑑於這個信息我最好的猜測會說你的instanceof操作符在運行時環境中是沒有意義的。我最好的建議是在討論規範的論壇中創建一個帖子:http://typescript.codeplex.com/discussions/topics/5488/language-specification。如果尚未支持,可能會讓他們考慮支持。 –

+0

@ErikNedwidek已經在此:) –

回答

5

類型體系全部刪除。你可以在任何泛型函數的生成代碼中看到這一點。

這就是說,對於類,還是有一些運行時信息。你可以這樣寫:

class A { } 
class B { } 
function As<T>(n: any, type: { new(...args: any[]): T }): T { 
    if(n instanceof type) { 
     return n; 
    } else { 
     return null; 
    } 
} 

var x = new A(); 
var y = new B(); 
console.log(As(x, A)); 
console.log(As(x, B)); 
+0

在運行時保留類型的類型參數非常有意義,但是我想知道爲什麼TypeScript設計者決定在生成的js代碼中完全刪除泛型類型?請參閱原始文章中的更新 –

+0

@KamyarNazeri「具有在運行時保留類型的類型參數非常有用」。但是,JavaScript不是鴨式語言嗎?由於目標環境不具有類型的概念,因此對於完整類型的擦除來說它是非常有意義的。 – Aron

+0

@Aron我相信你誤解我的意思。考慮到方法簽名被保留,*參數*被保存在編譯後的js文件中!然而,它是通用類型聲明 - 當不存在於方法簽名中時 - 通過類型擦除來刪除。此外,JavaScript是一種鴨式語言,但TypeScript是JavaScript的超集,我認爲泛型類型擦除可能會有點問題 –