2014-10-22 57 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到您的项目。

希望有所帮助。


*我对古典团队

相关问题