1. ホーム
  2. typescript

[解決済み] ジェネリッククラスの型パラメータから新しいオブジェクトを作成する

2022-04-20 12:19:51

質問

ジェネリッククラスでパラメータ型の新しいオブジェクトを作成しようとしています。 私のクラスでは 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;
        }
    }
}

汎用型からオブジェクトを作成することはできますか?

どのように解決するのですか?

コンパイルされたJavaScriptは型情報がすべて消去されているので T を使用してオブジェクトを新規作成します。

コンストラクタに型を渡すことで、汎用的でない方法でこれを行うことができます。

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