2013-01-15 12 views
70

で「インターフェース」の違いは何ですか?が好ましく、その理由である.d.tsソース宣言ファイルを作成するとき、「クラスを宣言」し、活字体で活字体

declare class Example { 
    public Method(): void; 
} 

または

interface Example { 
    Method(): void; 
} 

私が言うことができるの違いは、インタフェースは、静的メソッドを持つことができないということですので、あなたはそれのためにクラスを使用する必要があります。どちらもJS出力を生成しないので、おそらくそれは問題ではありませんか?実装は、「他の場所」であるので - declare class構文は本当に活字体で書かれていない外部コードのための型定義を追加するために使用されることを意図しているのに対し

class MyClass implements Example { 
    Method() { 

    } 
} 

+0

参照http://stackoverflow.com/a/14323673/1704166 –

+0

これらのどちらも、JS出力なしで同じことを達成できるため、別のものを使用することを説明するのに役立つとは思われません。 – Chris

答えて

118

interfaceは、あなたは、単にオブジェクトの形状を記述したいときのためです。インターフェイスのコード生成はこれまでどおりではありません。タイプシステムのアーティファクトだけです。あなたはそれがimplements句を持っているかどうかに応じて、クラスのコード生成に差は見られないだろう。あなたは、外部に存在することになるだろう既存クラス(通常は活字体クラス、常にではない)を記述したい場合(たとえば、次の2つの.jsにコンパイル2つの.TSファイルを持っているため

declare classですファイルは両方ともウェブページのscriptタグを介して含まれています)。あなたがextendsを使用してclassから継承する場合は(関係なく、基本型がdeclare classまたは通常classあったかどうかの)コンパイラは、プロトタイプチェーンとフォワーディングのコンストラクタをフックするすべてのコードを生成するために行くと何をされていません。

インタフェースであったはずのdeclare classから継承しようとすると、生成されたコードが実行時の表現を持たないオブジェクトを参照するため、ランタイムエラーが発生します。

逆に、implementのインターフェイスがdeclare classであった場合は、すべてのメンバーを自分で再実装する必要があります。また、コードを再利用することもできません。基底クラスで、実行時にプロトタイプチェーンをチェックする機能は、実際には、基本クラスのインスタンスではないものとして、あなたのオブジェクトを拒否します。

あなたがC++バックグラウンドを持っている場合、あなたはおおよそ厳密にこのコンパイル単位で定義を欠いコンストラクタのextern宣言としてtypedefとしてinterfacedeclare classと考えることができ、本当にオタク取得します。

純粋な消費側(命令型コードを記述し、新しい型を追加しない)から、interfaceとの唯一の違いは、インタフェースがnewでないことです。あなたはextend/implementに新しいclassでこれらのタイプのいずれかを意図する場合は、あなたは絶対にinterfacedeclare classの間で正しく選択されている必要があります。それらのうちの1つだけが動作します。あなたによく機能します

つのルール:

  • は、コンストラクタ関数(newで呼び出し可能なもの)を持つタイプの整列の名前であることが、実行時に実際に存在します(例えばDateがあるが、JQueryStaticではありません) ? である場合は、間違いなくinterface
  • 私は別のTypeScriptファイルのコンパイルされたクラスを扱っていますか?はい場合は、それがない場合であっても、素人の面ではdeclare class
+0

実際にはtypescriptでインターフェースを新規作成することができます。唯一の制限は継承です。 –

+2

インタフェース型で 'new'演算子を呼び出すことはできません。しかし、インタフェースは構造体シグニチャを持つことができます。つまり、インタフェース型の値に対して 'new'演算子を呼び出すことができます。これは 'class'がどのように動作するかとは非常に異なります。構造体の署名は、その型の式ではなく、型名自体にあります。 –

+0

コンストラクタをインターフェイスに追加するルートに行く場合は、クラスの 'statics'を除いて、インターフェイスの唯一のメンバである必要があります。コンストラクタ関数のインタフェースと構築されたオブジェクトのインタフェースを結合しないでください。そうした場合、型システムでは、new(new x())のような愚かさが許されます。x:Interfaceです。 –

12

あなたがインターフェイスを実装することができます。

+0

したがって、TypeScriptで記述されていないコードを宣言するためにdeclareクラスを使用することをお勧めしますか?私はその場合、jquery.d.tsファイルにチェックインされていると仮定しますが、JQueryStaticは次のインターフェイスで実装されています。 宣言var $:JQueryStatic これは持っていますが 宣言クラス$ { public static .. 。 } – Chris

+0

私がこれについて考えることができる唯一の理由は、人々がクラスを拡張することを望まない場合です。インターフェイスを使用すると、実装全体を提供する必要があることを意味します。 – Fenton

+0

意味があります。おそらくそれが理由でした。 – Chris

3

declareは、我々はその環境に存在するdeclaringだキーワードを期待すべきコンパイラに伝えるために.ts/d.tsファイルで使用される使用現在のファイルで定義されています。これにより、宣言されたオブジェクトを使用する際に型の安全性が確保されます。Typescriptコンパイラは、他のコンポーネントがその変数を提供する可能性があることを知っています。

関連する問題