Passing-Klasse als Parameter Ursachen „nicht newable“ Fehler

stimmen
35

Ich versuche, eine Klasse als Parameter an eine Funktion zu übergeben, die diese Klasse instanziiert werden und gibt es zurück. Hier ist mein Code:

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

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

Wenn ich versuche, dies zu kompilieren, erhalte ich:

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

Was mache ich falsch?

Wenn ein newable Typ-Wert ist ein Objektkonstruktor, wie ich die Konstruktor-Funktion zur Laufzeit übergeben kann?

Veröffentlicht am 09/10/2012 um 15:30
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
48

Wir brauchen etwas zu sagen typeof (MyClass) Objekte von Klassen in Funktionssignaturen zu unterscheiden.

Wie auch immer, Sie können Sie tatsächlich lösen Problem durch Konstruktortyp Signatur. In Anbetracht dieser Klasse:

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

Um diese Klasse als eine Art übergeben, die Sie dann in einer Funktion instanziiert, haben Sie eigentlich die Klasse Konstruktor Signatur wie diese zu kopieren:

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

EDIT: Es gibt eine einfache Lösung auf Codeplex gefunden:

Sie haben eine Schnittstelle für Ihre Klasse wie folgt zu erstellen:

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

Dann verwenden Sie es in Ihrer Funktion Unterschrift:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
Beantwortet am 13/10/2012 um 09:45
quelle vom benutzer

stimmen
14

Versuche dies:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
Beantwortet am 28/06/2016 um 16:18
quelle vom benutzer

stimmen
6

Es gibt zwei Möglichkeiten, Klassen in Typoskript zu übergeben. Wenn du:

  • kennen die Oberklasse der Klasse Sie , die durch (bereits von Corey Alix empfohlen):

    class MyClass extends MySuperClass{ }
    
    makeMyClass(classRef: typeof MySuperclass) {
        return new classRef();
    }
    
    makeMyClass(MyClass);
    
  • wissen die Unterschrift der Klassen Konstruktorfunktion :

    class MyClass {
        constructor(arg: string) {}
    }
    
    makeMyClass(classRef: { new(arg: string) }) {
        return new classRef('hello');
    }
    
    makeMyClass(MyClass);
    
Beantwortet am 25/04/2017 um 14:24
quelle vom benutzer

stimmen
2

In Ergänzung zu den anderen Antworten; Ich habe ein Dienstprogramm Typ I um halten einen allgemeinen Parameter, um sicherzustellen, / Feld ist eine Klasse / newable:

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

Anschließend können Sie sicherstellen, dass Sie eine Klasse Konstruktor erhalten:

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

der Newable<T>Ansatz funktioniert , wo typeof T--Wo Teine generische type-- ist nicht.

Zum Beispiel: register<T extends TViewBase>(view: typeof T)Ergebnisse in dem folgenden Fehler:

[Ts] ‚T‘ bezieht sich nur auf eine Art, aber hier als Wert verwendet wird.

Beantwortet am 31/08/2017 um 14:06
quelle vom benutzer

stimmen
2

Ich weiß, das ist eine alte Frage, aber hier geht:

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

Antwort wurde gefunden hier .

Beantwortet am 02/07/2017 um 18:06
quelle vom benutzer

stimmen
0

Je nach Situation, die drei Lösung unten ist vielleicht nicht genug:

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

Es gibt Fälle , wo man einige nennen möchte statisch wie Methoden myClass.someMethod(). 1und 2wird nicht zulassen , dass Sie das tun (und pls nie in Ihrer Anwendung verwenden) , weil sie nicht wissen , über diese Methode.

Oder es gibt Fälle , in denen Sie haben wollen , MyClassals eine abstrakte Klasse und erstellen eine Instanz von myClass mit let instance = new myClass. In diesem Fall 3wird fehlschlagen.

Was ich in diesen Fällen zu tun ist eine besondere Art zu schaffen , MyClassdass die Probleme lösen werde ich oben hervorgehoben, die etwa wie folgt aussieht:

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

BTW. Vergessen Sie nicht, Rückgabetypen auf Ihre Methoden hinzufügen, damit Sie die richtige intellisense bekommen.

Beantwortet am 04/10/2019 um 18:36
quelle vom benutzer

stimmen
-1

Vielen Dank für das Wesentliche - eine leichte Veränderung alles funktionieren macht. Im Beispiel unten, wir „neuen up“ die TestViewin der konkreten Testansicht zu passieren, anstatt auf neues es innerhalb der Methode versuchen.

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())
Beantwortet am 09/10/2012 um 16:09
quelle vom benutzer

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