la clase que pasa como causas de parámetros "no es newable" error

votos
35

Estoy tratando de pasar una clase como un parámetro para alguna función, que será una instancia de esta clase y lo devuelve. Aquí está mi código:

module A.Views {
  export class View { ... }
}

module A.App {
  export class MyApp {
    ...
    registerView(viewKlass:A.Views.View):void
    {
        var test = new viewKlass;
    } 
  }
}

Cuando estoy tratando de compilar este, estoy consiguiendo:

(...): Value of type 'Views.View' is not newable.

¿Qué estoy haciendo mal?

Si un valor de tipo newable es un constructor de objetos ¿cómo paso la función constructora en tiempo de ejecución?

Publicado el 09/10/2012 a las 15:30
fuente por usuario
En otros idiomas...                            


7 respuestas

votos
48

Necesitamos algo que decir typeof (MiClase) para distinguir los objetos de clases en las firmas de función.

De todos modos, en realidad se puede resolver el problema mediante el uso de la firma de tipo constructor. Teniendo en cuenta esta clase:

class MyClass {
    constructor (private name: string) {
    }
}

Para pasar esa clase como un tipo que entonces se puede crear una instancia de una función, que realmente tiene que duplicar la firma constructor de la clase de esta manera:

function sample(MyClass: new (name: string) => MyClass) {
    var obj = new MyClass("hello");
}

EDIT: Hay una solución simple que se encuentra en CodePlex:

Hay que crear una interfaz para su clase como esta:

interface IMyClass {
    new (name: string): MyClass;
}

A continuación, utilizarlo en su firma de la función:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
Respondida el 13/10/2012 a las 09:45
fuente por usuario

votos
14

Prueba esto:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
Respondida el 28/06/2016 a las 13:18
fuente por usuario

votos
6

Hay 2 formas de pasar las clases a máquina de escribir. Si tu:

  • conocer la superclase de la clase estás pasando por (ya recomendados por Corey Alix):

    class MyClass extends MySuperClass{ }
    
    makeMyClass(classRef: typeof MySuperclass) {
        return new classRef();
    }
    
    makeMyClass(MyClass);
    
  • conocer la firma de la función de las clases constructor :

    class MyClass {
        constructor(arg: string) {}
    }
    
    makeMyClass(classRef: { new(arg: string) }) {
        return new classRef('hello');
    }
    
    makeMyClass(MyClass);
    
Respondida el 25/04/2017 a las 11:24
fuente por usuario

votos
2

Como complemento a las otras respuestas; Tengo una utilidad de tipo guardo todo para asegurar un parámetro genérico / campo es una clase / newable:

/* new T() */
export type Newable<T> = { new (...args: any[]): T; };

A continuación, puede asegurarse de que obtiene un constructor de la clase:

class MyApp<TViewBase>
{
  register<TView extends TViewBase>(view: Newable<TView>) { 
  }
}

el Newable<T>enfoque funciona en typeof T--donde Tes una type-- genérica no.

Por ejemplo: register<T extends TViewBase>(view: typeof T)los resultados en el error siguiente:

[Ts] 'T' sólo se refiere a un tipo, pero se utiliza como un valor aquí.

Respondida el 31/08/2017 a las 11:06
fuente por usuario

votos
2

Sé que esto es una vieja pregunta, pero aquí va:

...
registerView(viewKlass: { new(): A.Views.View }):void
{
    var test = new viewKlass();
} 

Se encontró respuesta aquí .

Respondida el 02/07/2017 a las 15:06
fuente por usuario

votos
0

Dependiendo de su situación, el fuelle de tres solución podría no ser suficiente:

  1. myClass: new (name: string) => MyClass
  2. interface IMyClass { new (name: string): MyClass; }; myClass: IMyClass
  3. myClass: typeof MyClass

Hay casos en los que le gustaría llamar a algunos estáticas métodos como myClass.someMethod(). 1y 2no se le permitirá hacer eso (y los pls no utilizar ninguna en su aplicación) porque no saben acerca de ese método.

O hay casos en los que desea tener MyClasscomo una abstracta clase y crear una instancia de myClass con let instance = new myClass. En ese caso, 3se producirá un error.

Lo que hago en estos casos es el de crear un tipo especial de MyClassque va a resolver los problemas que se indica arriba, que es como la siguiente:

type MyClassContructor<T extends MyClass> = typeof MyClass & Constructor<T>;

Por cierto. No se olvide de añadir tipos de retorno a sus métodos para que pueda obtener intellisense adecuada.

Respondida el 04/10/2019 a las 18:36
fuente por usuario

votos
-1

Gracias por la esencia - un ligero cambio hace que todo buen trabajo. En el siguiente ejemplo, "nuevo" el TestViewque pasamos en la vista de la prueba concreta, en lugar de tratar de nuevo dentro del método.

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())
Respondida el 09/10/2012 a las 16:09
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more