Passen klasse als parameter oorzaken "is niet newable" fout

stemmen
35

Ik ben op zoek naar een klasse als parameter voor een functie, dat deze klasse zal instantiëren en terug te sturen. Hier is mijn code:

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

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

Wanneer ik probeer om dit te compileren, krijg ik:

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

Wat doe ik verkeerd?

Als een soort newable waarde een object constructor hoe ik langs de constructorfunctie runtime?

De vraag is gesteld op 09/10/2012 om 15:30
bron van user
In andere talen...                            


7 antwoorden

stemmen
48

We hebben iets te zeggen typeof (MyClass) om objecten uit klassen onderscheiden in functie handtekeningen.

Hoe dan ook, je kunt eigenlijk u op te lossen probleem op door het gebruik van het type constructeur handtekening. Gezien deze klasse:

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

Om die klasse als een type dat u vervolgens kunt instantiëren in een functie pas, je eigenlijk tot de klasse constructor handtekening als volgt te dupliceren:

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

EDIT: Er is een eenvoudige oplossing te vinden op CodePlex:

Je moet een interface voor je klas als dit te maken:

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

Vervolgens gebruiken in uw functie signature:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
antwoordde op 13/10/2012 om 09:45
bron van user

stemmen
14

Probeer dit:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
antwoordde op 28/06/2016 om 16:18
bron van user

stemmen
6

Er zijn 2 manieren om klassen passeren met de schrijfmachine. Als jij:

  • weet dat de superklasse van de klasse waarin u op doorreis bent (reeds door Corey Alix aanbevolen):

    class MyClass extends MySuperClass{ }
    
    makeMyClass(classRef: typeof MySuperclass) {
        return new classRef();
    }
    
    makeMyClass(MyClass);
    
  • weten de ondertekening van de klassen constructorfunctie :

    class MyClass {
        constructor(arg: string) {}
    }
    
    makeMyClass(classRef: { new(arg: string) }) {
        return new classRef('hello');
    }
    
    makeMyClass(MyClass);
    
antwoordde op 25/04/2017 om 14:24
bron van user

stemmen
2

Om de andere antwoorden aan te vullen; Ik heb een utility type I te houden rond om een ​​generieke parameter te verzekeren / gebied is een klasse / newable:

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

Vervolgens kunt u ervoor zorgen dat u een klasse constructor:

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

de Newable<T>aanpak werkt, waar typeof T--waar Tis een generieke Motortype- niet.

Bijvoorbeeld: register<T extends TViewBase>(view: typeof T)de resultaten in de volgende foutmelding:

[Ts] T verwijst slechts in type, maar wordt gebruikt als een waarde in.

antwoordde op 31/08/2017 om 14:06
bron van user

stemmen
2

Ik weet dat dit een oude vraag, maar hier gaat:

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

Antwoord werd gevonden hier .

antwoordde op 02/07/2017 om 18:06
bron van user

stemmen
0

Afhankelijk van uw situatie, kan de drie oplossing blaten niet genoeg zijn:

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

Er zijn gevallen waarin u zou willen sommigen noemen statische methoden zoals myClass.someMethod(). 1en 2zal niet toestaan dat u om dat te doen (en pls gebruik nooit in uw app), omdat ze niet weten over die methode.

Of zijn er gevallen waarin je wilt hebben MyClassals een abstracte klasse en een instantie van myClass met let instance = new myClass. In dat geval 3zal mislukken.

Wat ik doe in deze gevallen is een speciaal type te maken voor MyClassdat zal de kwesties die ik hierboven benadrukt, dat er ongeveer zo uitziet op te lossen:

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

BTW. Vergeet niet om terugkeer types toe te voegen aan uw methodes, zodat u de juiste intellisense krijgen.

antwoordde op 04/10/2019 om 18:36
bron van user

stemmen
-1

Dank u voor de essentie - een kleine verandering maakt het werken allemaal prima. In het onderstaande voorbeeld, we "nieuwe up" van de TestViewdoor te geven in het beton testweergave, veeleer dan te proberen om nieuwe binnen de methode.

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())
antwoordde op 09/10/2012 om 16:09
bron van user

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