183

ジェネリック クラスで型パラメーターの新しいオブジェクトを作成しようとしています。私のクラスViewには、型パラメーターとして渡されるジェネリック型のオブジェクトの 2 つのリストがありますが、作成しようとするとnew TGridView()、TypeScript は次のように言います。

シンボル 'TGridView が見つかりませんでした

これはコードです:

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;
        }
    }
}

ジェネリック型からオブジェクトを作成できますか?

4

12 に答える 12

178

ジェネリック コード内で新しいオブジェクトを作成するには、そのコンストラクター関数によって型を参照する必要があります。したがって、これを書く代わりに:

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

これを書く必要があります:

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

var classA: ClassA = activator(ClassA);

この質問を参照してください: クラス引数を使用したジェネリック型推論

于 2014-11-02T05:52:36.053 に答える
114

Tコンパイルされた JavaScript はすべての型情報が消去されているため、オブジェクトを新しくするために使用することはできません。

型をコンストラクターに渡すことにより、非ジェネリックな方法でこれを行うことができます。

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();

ジェネリックを使用してこの例を拡張し、型を強化できます。

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();
于 2013-06-29T19:16:29.763 に答える
44

すべての型情報は JavaScript 側で消去されるため、@Sohnee の状態のように T を新しくすることはできませんが、型付きパラメーターをコンストラクターに渡すことをお勧めします。

class A {
}

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

var test = new B<A>(A);
于 2016-01-18T13:39:26.917 に答える
0

私はこれを使用します:let instance = <T>{}; それは一般的に動作します編集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]);
  }
}
于 2017-10-03T15:07:57.173 に答える