10

私は TypeScript のコンストラクト シグネチャを使用するインターフェイスで少し遊んでいましたが、次の型チェックに失敗したときに少し混乱しました。

class Foo {
    constructor () {
    }
}

interface Bar {
    new(): Bar;
}

function Baz(C : Bar) {
    return new C()
}

var o = Baz(Foo);

タイプエラーは次のとおりです。

指定されたパラメータは呼び出しターゲットのシグネチャと一致しません: タイプ 'new() => Foo' および 'Bar' のコンストラクト シグネチャは互換性がありません: タイプ 'Bar' にはコンストラクト シグネチャが必要ですが、タイプ 'Foo' にはコンストラクト シグネチャがありません (C: Bar ) => バー

Foo のコンストラクターの型は () => Foo であり、それが Bar が言っていることだと思いました。ここで何か不足していますか?

4

5 に答える 5

5

これは、微妙な変更を加えた更新バージョンのコードです。

Bar存在すると予想される関数と変数を使用してインターフェイスを定義します。

Bar次に、インターフェースを使用してインターフェースを拡張しNewableBarます。これは、 を返すコンストラクターを定義したところBarです。

Foo実装Barし、コンストラクターを持ち、 をBaz必要とするためNewableBar、すべてがチェックされます。

これは - よりも少し冗長ですanyが、必要なチェックを行います。

interface Bar {

}

interface NewableBar extends Bar {
    new();
}

class Foo implements Bar {
    constructor () {

    }
}

function Baz(C : NewableBar) {
    return new C()
}

var o = Baz(Foo);
于 2012-10-18T11:18:14.557 に答える
2

問題は (少なくとも TypeScript コンパイラの観点からは)Barnewメソッドのシグネチャです。Barの定義を次のように置き換えると、

interface Bar {
  new (): any;
}

できます。戻り値が機能しないnew (): Fooのと同じように、 を使用することもできます。Bar

于 2012-10-18T10:26:48.033 に答える
1

私はあなたがこれをどこで取っているかを知っていると思います.そして、微妙に異なるアプローチが必要だと思います.

この例は次のように述べています。

  • Bazには、新しいアイテムを渡す必要があります。
  • バズはバーを返します
  • すべての Bar が newable である必要はありません。Baz に渡されるものだけです。

次に例を示します。

interface Bar {
    sayHello(name: string): void;
}

interface Newable {
    new();
}

class Foo implements Bar {
    constructor () {

    }

    sayHello(name: string) {
        window.alert('Hello ' + name);
    }
}

function Baz(C : Newable) {
    return <Bar> new C()
}

var o = Baz(Foo);
o.sayHello('Bob');

このアプローチの唯一の危険は、Bar ではない newable を Baz 関数に渡すことができることです。引数からオブジェクトを作成することによって動的機能を使用しているため、事前に初期化されたオブジェクトを渡そうとしない限り、これはほとんど避けられません。

于 2012-10-18T14:51:11.320 に答える