2014-10-22 54 views
0

我想定義一個函數,它的參數是一個構造函數。在函數內,我想訪問構造函數的name屬性。是否可以使用TypeScript創建此類型約束?如何爲具有'name'屬性的類指定類型?

function doSomethingWithAConstructor(ctor: { new(); name: string }): string { 
    return ctor.name; 
} 

更新:

預期的用法是:

class A {} 

doSomethingWithAConstructor(A); 

回答

1

發佈的代碼是特定於零參數構造,這就是爲什麼它拒絕類,它們的構造函數有一個以上的論據。您可以使用...來指示任意數量的參數。

功能上的name屬性特定於ES6,因此不屬於Function的TypeScript定義的一部分。 請注意,IE11尚不支持此屬性,因此請自行承擔兼容性問題的風險。你可以把它添加到Function全局類型,如果你想:

interface Function { 
    name: string; 
} 

function doSomethingWithAConstructor(ctor: { new (...args: any[]): any; }): string { 
    return ctor.name; 
} 

或者你可以在函數體中使用類型斷言:

function doSomethingWithAConstructor(ctor: { new (...args: any[]): any; }): string { 
    var c = <{name: string;}><any>ctor; 
    return c.name; 
} 
+0

由於開發商之一,但並不完全符合我要的。查看我的更新。 – liammclennan 2014-10-22 04:09:12

1

功能在ES6名稱,將在一些實施JavaScript環境,as noted here on MDN。然而在TypeScript中,Function.name不存在,因爲它定位於ES3或ES5。但是TypeScript允許你擴展接口。所以,你可能想要做的第一件事就是添加到您的文件的頂部:

interface Function { name: string; } 

接下來的事情要注意的是,有沒有什麼特別的構造,它僅僅是一個函數。因此,寫你的函數正確的做法是:

function doSomethingWithAConstructor(ctor: Function): string { 
    return ctor.name; 
} 

如果你想保護自己免受尚未實施Function.name環境,和/或你願意通過約定來定義構造函數他們都是以大寫字母開頭的唯一功能,將其添加爲你的函數的第一行:

function doSomethingWithAConstructor(ctor: Function): string { 
    if (!ctor || !ctor.name || ctor.name[0] === ctor.name[0].toLowerCase()) 
     throw 'Please specify a constructor'; 

    return ctor.name; 
} 

最後,還有一個名爲Classical.js *庫,使這要容易得多。首先,功能接口擴展不是必需的。其次,ES6不是必需的 - 如果沒有定義,名稱將從函數定義中解析出來。下面的代碼是什麼樣子:

function doSomethingWithAConstructor(ctor: Function): string { 
    return typeOf(ctor).name; 
} 

或者甚至

class A {} 
typeOf(A).name; //'A' 

如果您想嘗試一下,請訪問Classical.js link,下載代碼,打開bin和添加classical.js和classical.d.ts到您的項目。

希望有所幫助。


*我對古典團隊

相關問題