48

実行時にクラスとコンストラクターの詳細を取得するtypescriptクラスをインスタンス化できるようにしたいと思います。私が書きたい関数は、クラス名とコンストラクターパラメーターを受け取ります。

export function createInstance(moduleName : string, className : string, instanceParameters : string[]) {
    //return new [moduleName].[className]([instancePameters]); (THIS IS THE BIT I DON'T KNOW HOW TO DO)
}
4

9 に答える 9

30

あなたは試すことができます:

var newInstance = Object.create(window[className].prototype);
newInstance.constructor.apply(newInstance, instanceparameters);
return newInstance;

編集このバージョンは、TypeScript プレイグラウンドを使用して動作しています。例を次に示します。

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

//instance creation here
var greeter = Object.create(window["Greeter"].prototype);
greeter.constructor.apply(greeter, new Array("World"));

var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function() {
    alert(greeter.greet());
}

document.body.appendChild(button);
于 2013-03-11T13:09:07.097 に答える
25

TypeScript を使用しているので、ロードされたオブジェクトを型付けする必要があると想定しています。これがサンプルクラスです (たとえば、多くの実装の 1 つをロードすることを選択しているため、インターフェイスも含まれています)。

interface IExample {
    test() : string;
}

class Example {
    constructor (private a: string, private b: string) {

    }

    test() {
        return this.a + ' ' + this.b;
    }
}

したがって、ある種のローダーを使用して実装を返すことになります。

class InstanceLoader {
    constructor(private context: Object) {

    }

    getInstance(name: string, ...args: any[]) {
        var instance = Object.create(this.context[name].prototype);
        instance.constructor.apply(instance, args);
        return instance;
    }
}

そして、次のようにロードします。

var loader = new InstanceLoader(window);

var example = <IExample> loader.getInstance('Example', 'A', 'B');
alert(example.test());

現時点では、キャストがあります: <IExample>- しかし、ジェネリックが追加されると、これを廃止して代わりにジェネリックを使用できます。これは次のようになります (まだ言語の一部ではないことに注意してください!)

class InstanceLoader<T> {
    constructor(private context: Object) {

    }

    getInstance(name: string, ...args: any[]) : T {
        var instance = Object.create(this.context[name].prototype);
        instance.constructor.apply(instance, args);
        return <T> instance;
    }
}

var loader = new InstanceLoader<IExample>(window);

var example = loader.getInstance('Example', 'A', 'B');
于 2013-03-11T14:38:22.960 に答える
7

もう 1 つの方法は、ファイルを動的に呼び出して、new

// -->Import: it dynamically
const plug = await import(absPath);
const constructorName = Object.keys(plug)[0];

// -->Set: it
const plugin = new plug[constructorName]('new', 'data', 'to', 'pass');
于 2018-01-28T14:59:22.220 に答える