48

この TypeScript インターフェースを実装する (そして TypeScript コンパイラを満足させる) クラスを作成するにはどうすればよいですか?

interface MyInterface {
    (): string;
    text2(content: string);
}

この関連する回答を見ました: How to make a class implement a call signature in Typescript?

ただし、これは、インターフェイスに関数シグネチャのみが含まれている場合にのみ機能します。実装する追加のメンバー (関数 text2 など) がある場合は機能しません。

4

3 に答える 3

48

クラスは、typescript インターフェースで利用可能なすべてを実装することはできません。代表的な 2 つの例は、呼び出し可能なシグネチャとインデックス操作です。例:インデックス可能なインターフェイスを実装する

その理由は、インターフェースは主に、JavaScript オブジェクトが実行できることをすべて説明するように設計されているためです。したがって、非常に堅牢である必要があります。ただし、TypeScript クラスは、プロトタイプの継承をより OO の従来型/理解しやすい/入力しやすい方法で具体的に表すように設計されています。

そのインターフェイスに従うオブジェクトを引き続き作成できます。

interface MyInterface {
    (): string;
    text2(content: string);
}

var MyType = ((): MyInterface=>{
  var x:any = function():string { // Notice the any 
      return "Some string"; // Dummy implementation 
  }
  x.text2 = function(content:string){
      console.log(content); // Dummy implementation 
  }
  return x;
}
);
于 2013-05-12T14:49:14.423 に答える
10

これは、受け入れられた答えの詳細です。

私の知る限り、呼び出し署名を実装する唯一の方法は、関数/メソッドを使用することです。残りのメンバーを実装するには、この関数で定義するだけです。これは、C# や Java から来た開発者には奇妙に思えるかもしれませんが、JavaScript では普通のことだと思います。

JavaScript では、関数を定義してメンバーを追加するだけなので、これは簡単です。ただし、この例ではメンバーFunctionを定義していないため、TypeScript の型システムではこれが許可されていません。text2

したがって、目的の結果を得るには、関数でメンバーを定義するときに型システムをバイパスする必要があり、その後、結果をインターフェイス型にキャストできます。

//A closure is used here to encapsulate the temporary untyped variable, "result".
var implementation = (() => {
    //"any" type specified to bypass type system for next statement.
    //Defines the implementation of the call signature.
    var result: any = () => "Hello";

    //Defines the implementation of the other member.
    result.text2 = (content: string) => { };

    //Converts the temporary variable to the interface type.
    return <MyInterface>result;
})(); //Invokes the closure to produce the implementation

クロージャを使用する必要がないことに注意してください。結果のインターフェイス実装と同じスコープで一時変数を宣言するだけです。もう 1 つのオプションは、クロージャ関数に名前を付けて読みやすくすることです。

以下は、より現実的な例だと思います。

interface TextRetriever {
    (): string;
    Replace(text: string);
}

function makeInMemoryTextRetriever(initialText: string) {
    var currentText = initialText;
    var instance: any = () => currentText;
    instance.Replace = (newText: string) => currentText = newText;

    return <TextRetriever>instance;
}

var inMemoryTextRetriever = makeInMemoryTextRetriever("Hello");
于 2013-12-23T03:39:57.727 に答える