Pertanyaan Bagaimana cara membuat objek baru dari jenis parameter di kelas generik dalam naskah?


Saya mencoba membuat objek baru dari parameter jenis di kelas generik saya. Di kelas saya "View" Saya memiliki 2 daftar objek dari tipe generik yang dilewatkan sebagai parameter jenis, tetapi ketika saya mencoba membuatnya new TGridView() kata naskah Could not find symbol 'TGridView'...

Ini kodenya:

module AppFW {
    // Represents a view
    export class View<TFormView extends FormView, TGridView extends GridView> {
        // The list of forms 
        public Forms: { [idForm: string]: TFormView; } = {};

        // The list of grids
        public Grids: { [idForm: string]: TGridView; } = {};

        public AddForm(formElement: HTMLFormElement, dataModel: any, submitFunction?: (e: SubmitFormViewEvent) => boolean): FormView {
            var newForm: TFormView = new TFormView(formElement, dataModel, submitFunction);
            this.Forms[formElement.id] = newForm;
            return newForm;
        }

        public AddGrid(element: HTMLDivElement, gridOptions: any): GridView {
            var newGrid: TGridView = new TGridView(element, gridOptions);
            this.Grids[element.id] = newGrid;
            return newGrid;
        }
    }
}

Bisakah saya membuat objek dari tipe generik?


75
2018-06-29 16:10


asal


Jawaban:


Karena JavaScript yang dikompilasi memiliki semua informasi jenis yang terhapus, Anda tidak dapat menggunakannya T untuk menambah objek baru.

Anda dapat melakukan ini dengan cara non-generik dengan meneruskan tipe ke konstruktor.

class TestOne {
    hi() {
        alert('Hi');
    }
}

class TestTwo {
    constructor(private testType) {

    }
    getNew() {
        return new this.testType();
    }
}

var test = new TestTwo(TestOne);

var example = test.getNew();
example.hi();

Anda dapat memperluas contoh ini menggunakan obat generik untuk memperketat jenis:

class TestBase {
    hi() {
        alert('Hi from base');
    }
}

class TestSub extends TestBase {
    hi() {
        alert('Hi from sub');
    }
}

class TestTwo<T extends TestBase> {
    constructor(private testType: new () => T) {
    }

    getNew() : T {
        return new this.testType();
    }
}

//var test = new TestTwo<TestBase>(TestBase);
var test = new TestTwo<TestSub>(TestSub);

var example = test.getNew();
example.hi();

49
2018-06-29 19:16



Untuk membuat objek baru dalam kode generik, Anda perlu merujuk ke jenis berdasarkan fungsi konstruktornya. Jadi daripada menulis ini:

function activatorNotWorking<T extends IActivatable>(type: T): T {
    return new T(); // compile error could not find symbol T
}

Anda perlu menulis ini:

function activator<T extends IActivatable>(type: { new(): T ;} ): T {
    return new type();
}

var classA: ClassA = activator(ClassA);

Lihat pertanyaan ini: Inferensi Tipe Generik dengan Argumen Kelas


87
2017-11-02 05:52



Semua informasi jenis dihapus di sisi JavaScript dan karena itu Anda tidak dapat baru T seperti negara @Sohnee, tapi saya lebih suka mengetik parameter yang diteruskan ke konstruktor:

class A {
}

class B<T> {
    Prop: T;
    constructor(TCreator: { new (): T; }) {
        this.Prop = new TCreator();
    }
}

var test = new B<A>(A);

15
2018-01-18 13:39



export abstract class formBase<T> extends baseClass {

  protected item = {} as T;
}

Objeknya akan dapat menerima parameter apa pun, namun, tipe T hanya referensi naskah dan tidak dapat dibuat melalui konstruktor. Artinya, itu tidak akan membuat objek sub-kelas.


7
2018-01-16 11:53



saya menggunakan ini: let instance = <T>{}; biasanya berhasil EDIT 1:

export class EntityCollection<T extends { id: number }>{
  mutable: EditableEntity<T>[] = [];
  immutable: T[] = [];
  edit(index: number) {
    this.mutable[index].entity = Object.assign(<T>{}, this.immutable[index]);
  }
}

0
2017-10-03 15:07



Saya mencoba memberi contoh generik dari dalam kelas dasar. Tak satu pun dari contoh di atas berhasil bagi saya karena mereka membutuhkan jenis beton untuk memanggil metode pabrik.

Setelah meneliti untuk sementara tentang hal ini dan tidak dapat menemukan solusi online, saya menemukan bahwa ini tampaknya berhasil.

 protected activeRow: T = {} as T;

Potongan-potongan:

 activeRow: T = {} <-- activeRow now equals a new object...

...

 as T; <-- As the type I specified. 

Bersama

 export abstract class GridRowEditDialogBase<T extends DataRow> extends DialogBase{ 
      protected activeRow: T = {} as T;
 }

0
2017-10-09 22:54