Parametre nedenleri olarak geçirilmesi sınıf hatası "newable değil"

oy
35

Bu sınıf örneğini ve onu dönecektir bazı işleve parametre olarak bir sınıf geçmek çalışıyorum. İşte benim kodudur:

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

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

ben bu derlemek çalışıyorum zaman ben alıyorum:

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

Neyi yanlış yapıyorum?

Bir newable tip i değeri zamanında yapıcı işlevini geçmesi nasıl bir amacı yapıcı ise?

Oluştur 09/10/2012 saat 15:30
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
48

Biz typeof (Sınıfım) işlevi imzalar sınıfların nesneleri ayırt söyleyecek bir şey lazım.

Neyse, aslında yapıcı tipi imzasını kullanarak size sorunu çözebilir. Bu sınıf düşünüldüğünde:

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

sonra bir işlevde örneğini bir türü olarak o sınıf geçmek için, aslında bu gibi sınıf yapıcı imza çoğaltmak zorunda:

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

DÜZENLEME: CodePlex üzerinde bulunan basit bir çözüm var:

Böyle sınıfınız için bir arayüz oluşturmak zorunda:

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

Ardından, fonksiyon imza kullanmak:

function sample(MyClass: IMyClass) {
    var obj = new MyClass("hello");
}
Cevap 13/10/2012 saat 09:45
kaynak kullanıcı

oy
14

Bunu dene:

export class MyApp {
    registerView(viewKlass: typeof A.Views.View): void {
        var test = new viewKlass();
    } 
}
Cevap 28/06/2016 saat 16:18
kaynak kullanıcı

oy
6

Daktilo dersleri geçme 2 yolu vardır. Eğer sen:

  • Geçerek sınıfının üst sınıfı biliyorum (zaten Corey Alix tarafından önerilir):

    class MyClass extends MySuperClass{ }
    
    makeMyClass(classRef: typeof MySuperclass) {
        return new classRef();
    }
    
    makeMyClass(MyClass);
    
  • sınıflar yapıcı işlevinin imzasını biliyoruz :

    class MyClass {
        constructor(arg: string) {}
    }
    
    makeMyClass(classRef: { new(arg: string) }) {
        return new classRef('hello');
    }
    
    makeMyClass(MyClass);
    
Cevap 25/04/2017 saat 14:24
kaynak kullanıcı

oy
2

Diğer yanıtları desteklemek için; Ben genel bir parametre sağlamak için etrafında tutmak bir yardımcı türüne sahip / alan bir sınıf / newable geçerli:

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

Daha sonra bir sınıf yapıcısı elde etmenizi sağlayabilir:

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

Newable<T>nerede yaklaşım çalışır typeof T-dir; burada Tjenerik type-- gelmez olduğunu.

Örneğin: register<T extends TViewBase>(view: typeof T)Aşağıdaki hata sonuçları:

[Ts] 'T', sadece bir tür anlamına gelir, ancak burada bir değer olarak kullanılmaktadır.

Cevap 31/08/2017 saat 14:06
kaynak kullanıcı

oy
2

Bu eski bir soru ama buraya biliyoruz:

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

Cevap bulunmuştur burada .

Cevap 02/07/2017 saat 18:06
kaynak kullanıcı

oy
0

durumunuza bağlı olarak, üç çözüm feryat yeterli olmayabilir:

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

Biraz çağırmak istiyorum durumlar vardır statik gibi yöntemler myClass.someMethod(). 1ve 2bunu izin vermiyor (ve lütfen uygulamanızda herhangi birini kullanmak asla) onlar bu yöntem hakkında bilmiyorum çünkü edecektir.

Sahip istediğinizde Ya durumlar da vardır MyClassbir şekilde soyut sınıf ve ile myClass bir örneğini oluşturmak let instance = new myClass. Bu durumda, 3başarısız olur.

Ne bu gibi durumlarda yapılacak özel bir türü yaratmaktır MyClassben şuna benzer ki, yukarıda vurgulanan sorunları çözecek:

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

BTW. Doğru intellisense almak böylece yöntemlere dönüş türleri eklemek unutmayın.

Cevap 04/10/2019 saat 18:36
kaynak kullanıcı

oy
-1

Ana fikir için teşekkür ederiz - ufak bir değişiklik tüm çalışma ince yapar. Aşağıdaki örnekte, "yukarı yeni" TestViewyerine yönteme içinde yeni bunu çalışmak yerine, beton testi görünümünde geçmek.

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())
Cevap 09/10/2012 saat 16:09
kaynak kullanıcı

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