1. ホーム
  2. javascript

[解決済み] TypeScriptのdeclare classとinterfaceの違いとは?

2022-07-07 06:47:40

質問

TypeScriptで、ソース宣言ファイル.d.tsを作成する場合、どちらが良いか、またその理由は?

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

または

interface Example {
    Method(): void;
}

私が言える違いは、インターフェースは静的メソッドを持つことができないので、そのためにクラスを使わなければならないことです。どちらもJS出力はしないので、もしかしたら関係ないのかも?

解決方法は?

interface は、単にオブジェクトの形状を記述したいときのためのものです。インターフェイスにはコード生成がありません。クラスが implements 節があるかどうかによるクラスのコード生成の違いはありません。

declare class 既存の クラス(通常はTypeScriptのクラスですが、必ずしもそうとは限りません)が外部に存在する場合(例えば、二つの.tsファイルがあり、二つの.jsファイルにコンパイルされ、両方が script タグでインクルードされている場合など)。を継承している場合 class を使用して extends (ベース型が declare class であるか、通常の class を使用する場合、コンパイラはプロトタイプチェーンと転送コンストラクタをフックするためのすべてのコードを生成する予定です。

を継承しようとすると declare class から継承しようとすると、生成されたコードが実行時のマニフェストを持たないオブジェクトを参照することになるため、実行時エラーになります。

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

C++のバックグラウンドを持っている人なら、本当にオタクになるために、おおよそ次のように考えることができます。 interface として typedef そして declare classextern の宣言は、このコンパイルユニットでは厳密に定義されていないコンストラクタの宣言であることを示します。

純粋に消費する側(新しい型を追加するのではなく、命令的なコードを書く)からすると、唯一の違いは interfacedeclare class ができないことです。 new というインターフェースです。しかし、もしあなたが意図的に extend / implement これらのタイプのいずれかを新しい class の間で正しく選択されている必要があります。 interfacedeclare class . どちらか一方だけが動作します。

うまくいくのは2つのルール

  • 型名がコンストラクタ関数と一致しているか。 new で呼び出せるもの) と整合しているか (例えば Date はそうですが JQueryStatic は違う)?もし はありません の場合、あなたは間違いなく interface
  • 他のTypeScriptファイルからコンパイルされたクラス、または十分に類似したものを扱っているのでしょうか?もし の場合 であれば declare class