我正在尝试将一个类作为参数传递给某个函数,该函数将实例化该类并将其返回。这是我的代码:
module A.Views {
export class View { ... }
}
module A.App {
export class MyApp {
...
registerView(viewKlass:A.Views.View):void
{
var test = new viewKlass;
}
}
}
当我正在尝试编译时,我得到了:
(...): Value of type 'Views.View' is not newable.
我做错了什么?
如果newable类型值是对象构造函数,我如何在运行时传递构造函数?
答案 0 :(得分:66)
我们需要说typeof(MyClass)来区分对象和函数签名中的类。
无论如何,你可以通过使用构造函数类型签名来解决问题。 考虑这个课程:
class MyClass {
constructor (private name: string) {
}
}
要将该类作为可以在函数中实例化的类型传递,实际上必须复制类构造函数签名,如下所示:
function sample(MyClass: new (name: string) => MyClass) {
var obj = new MyClass("hello");
}
编辑: 在codeplex上有一个简单的解决方案:
你必须为你的类创建一个接口:
interface IMyClass {
new (name: string): MyClass;
}
然后,在函数签名中使用它:
function sample(MyClass: IMyClass) {
var obj = new MyClass("hello");
}
答案 1 :(得分:17)
试试这个:
export class MyApp {
registerView(viewKlass: typeof A.Views.View): void {
var test = new viewKlass();
}
}
答案 2 :(得分:9)
有两种方法可以在TypeScript中传递类。如果你:
了解您正在通过的课程的超类(已由Corey Alix推荐):
class MyClass extends MySuperClass{ }
makeMyClass(classRef: typeof MySuperclass) {
return new classRef();
}
makeMyClass(MyClass);
知道班级构造函数的签名:
class MyClass {
constructor(arg: string) {}
}
makeMyClass(classRef: { new(arg: string) }) {
return new classRef('hello');
}
makeMyClass(MyClass);
答案 3 :(得分:9)
补充其他答案;我有一个实用程序类型,以确保通用参数/字段是类/ newable:
/* new T() */
export type Newable<T> = { new (...args: any[]): T; };
然后,您可以确保获得类构造函数:
class MyApp<TViewBase>
{
register<TView extends TViewBase>(view: Newable<TView>) {
}
}
Newable<T>
方法适用于typeof T
- 其中T
是通用类型 - 不是。
例如:register<T extends TViewBase>(view: typeof T)
会导致以下错误:
[ts]&#39; T&#39;仅指类型,但在此处用作值。
答案 4 :(得分:3)
我知道这是一个老问题,但是这里有:
...
registerView(viewKlass: { new(): A.Views.View }):void
{
var test = new viewKlass();
}
找到了答案here。
答案 5 :(得分:0)
根据您的情况,以下三种解决方案可能还不够:
myClass: new (name: string) => MyClass
interface IMyClass {
new (name: string): MyClass;
};
myClass: IMyClass
myClass: typeof MyClass
在某些情况下,您想调用某些静态方法,例如myClass.someMethod()
。 1
和2
不允许您这样做(并且请不要在您的应用程序中使用任何东西),因为他们不知道该方法。
或者在某些情况下,您想将MyClass
作为抽象类,并使用let instance = new myClass
创建myClass的实例。在这种情况下,3
将失败。
在这些情况下,我要做的是为MyClass
创建一种特殊类型,该类型将解决上面突出显示的问题,如下所示:
type MyClassContructor<T extends MyClass> = typeof MyClass & Constructor<T>;
顺便说一句。不要忘记将返回类型添加到您的方法中,以便获得适当的智能感知。
答案 6 :(得分:0)
在使用Angular的情况下,它们具有implemented Type
,类似于Meirion Hughes answer:
import {Type} from '@angular/core';
export class MyApp {
...
registerView(viewKlass: Type<A.Views.View>):void
{
var test = new viewKlass();
}
}
答案 7 :(得分:-1)
感谢您的要点 - 稍微改变一下就可以了。在下面的示例中,我们“新建”TestView
以传递具体的测试视图,而不是尝试在方法中新建它。
module V.Views {
export class View {
public someVar: any;
// the presence of constructor doesn't affect the error triggering
}
}
module V.App {
export class Application {
public registerView(url: string, viewKlass: V.Views.View): void
{
var test = viewKlass;
}
}
}
var app = new V.App.Application;
class TestView extends V.Views.View {
}
class TestView2 extends V.Views.View {
}
app.registerView('', new TestView())
app.registerView('content/view/:slug/', new TestView2())