我想定义一个具有构造函数的参数的函数。在函数中我想访问构造函数的name
属性。是否可以使用TypeScript创建此类型约束?
function doSomethingWithAConstructor(ctor: { new (); name: string }): string {
return ctor.name;
}
更新:
预期用途是:
class A {}
doSomethingWithAConstructor(A);
答案 0 :(得分: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;
}
答案 1 :(得分: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 *的库让这更容易。首先,不需要Function接口扩展。其次,不需要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添加到您的项目中。
希望有所帮助。
*我是古典团队的开发人员之一