Passing class as parameter causes "is not newable" error
I'm trying to pass a class as a parameter to some function, that will instantiate this class and return it. Here is my code:
module A.Views {
export class View { ... }
}
module A.App {
export class MyApp {
...
registerView(viewKlass:A.Views.View):void
{
var test = new viewKlass;
}
}
}
When i'm trying to compile this, i'm getting:
(...): Value of type 'Views.View' is not newable.
What am I doing wrong?
If a newable type value is an object constructor how do i pass the constructor function at runtime?
Solution 1:
We need something to say typeof(MyClass) to distinguish objects from classes in function signatures.
Anyway, you can actually solve you problem by using constructor type signature. Considering this class:
class MyClass {
constructor (private name: string) {
}
}
To pass that class as a type that you can then instantiate in a function, you actually have to duplicate the class constructor signature like this:
function sample(MyClass: new (name: string) => MyClass) {
var obj = new MyClass("hello");
}
EDIT : There is a simple solution found on codeplex:
You have to create an interface for your class like this:
interface IMyClass {
new (name: string): MyClass;
}
Then, use it in your function signature:
function sample(MyClass: IMyClass) {
var obj = new MyClass("hello");
}
Solution 2:
To supplement the other answers; I have a utility type I keep around to ensure a generic parameter/field is a class/newable:
/* new T() */
export type Newable<T> = { new (...args: any[]): T; };
You can then ensure you get a class constructor:
class MyApp<TViewBase>
{
register<TView extends TViewBase>(view: Newable<TView>) {
}
}
the Newable<T>
approach works where typeof T
--where T
is a generic type-- does not.
For example: register<T extends TViewBase>(view: typeof T)
results in the following error:
[ts] 'T' only refers to a type, but is being used as a value here.
Solution 3:
Try this:
export class MyApp {
registerView(viewKlass: typeof A.Views.View): void {
var test = new viewKlass();
}
}