Předávání třída jako příčiny parametr „není newable“ error

hlasů
35

Snažím se projít třídu jako parametr nějakou funkci, která bude vytvořit instanci této třídy a vrátit ji. Zde je můj kód:

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

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

Když se snažím sestavit toho začínám:

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

Co dělám špatně?

Je-li hodnota newable typ je objekt konstruktor Jak mohu předat funkci konstruktoru za běhu?

Položena 09/10/2012 v 15:30
zdroj uživatelem
V jiných jazycích...                            


7 odpovědí

hlasů
48

Musíme něco říci typeof (MyClass) rozlišit objekty z tříd podpisů funkcí.

Mimochodem, můžete skutečně vyřešit vám problém pomocí typu konstruktér podpis. S ohledem na tuto třídu:

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

Předat tuto třídu jako typ, který pak můžete vytvořit instanci ve funkci, jste skutečně duplikovat konstruktoru třídy podpis takto:

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

EDIT: Existuje jednoduché řešení nalézt na CodePlex:

Musíte vytvořit rozhraní pro svou třídu, jako je tento:

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

Potom použijte ji ve svém funkčním podpisu:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
Odpovězeno 13/10/2012 v 09:45
zdroj uživatelem

hlasů
14

Zkuste to:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
Odpovězeno 28/06/2016 v 16:18
zdroj uživatelem

hlasů
6

K dispozici jsou 2 způsoby, jak procházejí kurzy na psacím stroji. Jestli ty:

  • znát supertřídu třídy jste procházející (již doporučil Corey Alix):

    class MyClass extends MySuperClass{ }
    
    makeMyClass(classRef: typeof MySuperclass) {
        return new classRef();
    }
    
    makeMyClass(MyClass);
    
  • znát podpis funkce třídy konstruktoru :

    class MyClass {
        constructor(arg: string) {}
    }
    
    makeMyClass(classRef: { new(arg: string) }) {
        return new classRef('hello');
    }
    
    makeMyClass(MyClass);
    
Odpovězeno 25/04/2017 v 14:24
zdroj uživatelem

hlasů
2

Doplnit další odpovědi; Mám typ užitnou I držet kolem s cílem zajistit obecný parametr / pole je třída / newable:

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

Pak můžete zajistit, dostanete konstruktoru třídy:

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

Newable<T>přístup funguje, kde typeof T--where Tje obecný type-- není.

Například: register<T extends TViewBase>(view: typeof T)výsledky v následující chybě:

[Ts] ‚T‘ se vztahuje pouze na typ, ale je používán jako hodnota zde.

Odpovězeno 31/08/2017 v 14:06
zdroj uživatelem

hlasů
2

Vím, že to je stará otázka, ale tady jde:

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

Bylo zjištěno, odpověď zde .

Odpovězeno 02/07/2017 v 18:06
zdroj uživatelem

hlasů
0

V závislosti na situaci, možná tři řešení níže nebude stačit:

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

Existují případy, kdy byste chtěli volat některé statické metody, jako je myClass.someMethod(). 1a 2nedovolí vám k tomu, že (a pls nikdy použít některý ve vaší aplikaci), protože nevědí o této metodě.

Nebo existují případy, kdy chcete mít MyClassjako abstraktní třídy a vytvořit instanci Moje_třída s let instance = new myClass. V takovém případě 3se nezdaří.

Co mám dělat v těchto případech je vytvořit speciální typ pro MyClasskterý vyřeší problémy I bylo zdůrazněno výše, která vypadá nějak takto:

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

MIMOCHODEM. Nezapomeňte se přidat typy vrátit ke svým metodám, takže máte správné IntelliSense.

Odpovězeno 04/10/2019 v 18:36
zdroj uživatelem

hlasů
-1

Děkuji za podstaty - malá změna to všechno funguje v pořádku dělá. V níže uvedeném příkladu jsme „nový up jen“ TestViewpředat do zkušebního betonového pohledu, spíše než se snažit nový ji v rámci metody.

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())
Odpovězeno 09/10/2012 v 16:09
zdroj uživatelem

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