Περνώντας τάξη ως αιτίες παράμετρο «δεν είναι newable» σφάλμα

ψήφοι
35

Είμαι προσπαθεί να περάσει μια τάξη ως παράμετρος σε κάποια λειτουργία, που θα υπόσταση σε αυτή την κατηγορία και να την επιστρέψει. Εδώ είναι ο κωδικός μου:

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 αξία τύπος είναι ένας κατασκευαστής αντικείμενο Πώς μπορώ να περάσουν τη λειτουργία κατασκευαστή κατά το χρόνο εκτέλεσης;

Δημοσιεύθηκε 09/10/2012 στις 15:30
πηγή χρήστη
Σε άλλες γλώσσες...                            


7 απαντήσεις

ψήφοι
48

Πρέπει κάτι να πει typeof (MyClass) να διακρίνει αντικείμενα από τις κατηγορίες στις υπογραφές λειτουργία.

Τέλος πάντων, μπορείτε πραγματικά να λύσει το πρόβλημα με τη χρήση του τύπου κατασκευαστή υπογραφής. Λαμβάνοντας υπόψη αυτή την κατηγορία:

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

Για να περάσει αυτή την κατηγορία ως ένα είδος που μπορείτε στη συνέχεια να υπόσταση σε μια λειτουργία, που πραγματικά πρέπει να επαναλάβει την υπογραφή κατασκευαστή της κλάσης όπως αυτό:

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

EDIT: Υπάρχει μια απλή λύση που βρέθηκε για CodePlex:

Θα πρέπει να δημιουργήσετε μια διεπαφή για την τάξη σας όπως αυτό:

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

Στη συνέχεια, το χρησιμοποιούν στην υπογραφή σας λειτουργία:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
Απαντήθηκε 13/10/2012 στις 09:45
πηγή χρήστη

ψήφοι
14

Δοκιμάστε αυτό:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
Απαντήθηκε 28/06/2016 στις 16:18
πηγή χρήστη

ψήφοι
6

Υπάρχουν 2 τρόποι για να περάσουν μαθήματα στη γραφομηχανή. Αν εσύ:

  • γνωρίζουν την υπερκλάση της κλάσης είστε διέρχεται (ήδη συστήσει από 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);
    
Απαντήθηκε 25/04/2017 στις 14:24
πηγή χρήστη

ψήφοι
2

Για να συμπληρώσει τις άλλες απαντήσεις? Έχω ένα είδος κοινής ωφέλειας θα κρατήσει γύρω για να εξασφαλιστεί μια γενική παράμετρο / πεδίο είναι μια κατηγορία / 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--where Tείναι ένας γενικός type-- δεν.

Για παράδειγμα: register<T extends TViewBase>(view: typeof T)τα αποτελέσματα στον ακόλουθο σφάλμα:

[Ts] «Τ» αναφέρεται μόνο σε έναν τύπο, αλλά χρησιμοποιείται ως τιμή εδώ.

Απαντήθηκε 31/08/2017 στις 14:06
πηγή χρήστη

ψήφοι
2

Ξέρω ότι αυτό είναι ένα παλιό θέμα, αλλά εδώ πηγαίνει:

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

Η απάντηση βρέθηκε εδώ .

Απαντήθηκε 02/07/2017 στις 18:06
πηγή χρήστη

ψήφοι
0

Ανάλογα με την κατάστασή σας, η παρακάτω τρεις λύση δεν μπορεί να είναι αρκετό:

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

Υπάρχουν περιπτώσεις κατά τις οποίες θα ήθελα να ζητήσω κάποιες στατικές μεθόδους όπως myClass.someMethod(). 1και 2δεν θα σας επιτρέψει να το κάνουμε αυτό (και pls μην χρησιμοποιήσετε οποιαδήποτε εφαρμογή σας) γιατί δεν ξέρω για τη μέθοδο αυτή.

Ή υπάρχουν περιπτώσεις, όταν θέλετε να έχετε MyClassως αφηρημένη τάξη και να δημιουργήσουν μια παρουσία του MyClass με let instance = new myClass. Σε αυτή την περίπτωση, 3θα αποτύχει.

Τι να κάνω σε αυτές τις περιπτώσεις είναι να δημιουργηθεί ένα ειδικό τύπο για το MyClassότι θα λύσει τα προβλήματα που επισημαίνονται παραπάνω, η οποία μοιάζει κάπως έτσι:

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

BTW. Μην ξεχάσετε να προσθέσετε τύπους επιστροφή στις μεθόδους σας, ώστε να πάρει την κατάλληλη intellisense.

Απαντήθηκε 04/10/2019 στις 18:36
πηγή χρήστη

ψήφοι
-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())
Απαντήθηκε 09/10/2012 στις 16:09
πηγή χρήστη

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