131

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

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

また

interface Example {
    Method(): void;
}

私が知ることができる違いは、インターフェースは静的メソッドを持つことができないので、そのためのクラスを使用する必要があるということです。どちらもJS出力を生成しないので、おそらく問題ではありませんか?

4

4 に答える 4

180

interfaceオブジェクトの形状を単純に記述したい場合に使用します。インターフェイスのコード生成はありません。これらは型システムのアーティファクトにすぎません。implementsクラスに句があるかどうかによって、クラスのコード生成に違いは見られません。

declare classこれは、外部に存在する既存のクラス(通常はTypeScriptクラスですが、常にではありません)を記述したい場合(たとえば、2つの.jsファイルにコンパイルされる2つの.tsファイルがあり、両方がscriptタグを介して含まれている場合)です。 Webページで)。classusingから継承する場合extends(基本タイプがaであるdeclare classか通常であるかに関係なくclass)、コンパイラーは、プロトタイプチェーンと転送コンストラクターなどを接続するためのすべてのコードを生成します。

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

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

本当にオタクになるために、C ++のバックグラウンドを持っている場合は、このコンパイル単位での定義が厳密に欠けているコンストラクターの宣言interfaceとして大まかtypedefに考えることができます。declare classextern

interface純粋な消費側(新しい型を追加するのではなく、命令型コードを書く)から見ると、との唯一の違いは、インターフェースを作成declare classできないことです。newただし、これらのタイプのいずれextendimplementを新しいclassで使用する場合は、との間で正しく選択する必要がinterfaceありdeclare classます。それらの1つだけが機能します。

あなたに役立つ2つのルール:

  • new型の名前は、実行時に実際に存在するコンストラクター関数(で呼び出すことができるもの)と一致していますか(たとえばDate、そうでJQueryStaticはありません)?いいえの場合、あなたは間違いなく欲しいinterface
  • 別のTypeScriptファイルからコンパイルされたクラス、または十分に類似したものを扱っていますか?はいの場合は、declare class
于 2013-01-15T22:27:16.760 に答える
27

次のインターフェースを実装できます。

class MyClass implements Example {
    Method() {

    }
}

構文は、TypeScriptで記述されていない外部コードの型定義を追加するために実際に使用されることを目的としているのに対しdeclare class、実装は「他の場所」にあります。

于 2013-01-15T20:38:13.343 に答える
15

素人の用語では、は/ファイルdeclareで使用され、現在のファイルで定義されていない場合でも、その環境に存在するキーワードを期待する必要があることをコンパイラに通知します。これにより、Typescriptコンパイラは他のコンポーネントがその変数を提供する可能性があることを認識しているため、宣言されたオブジェクトを使用するときに型の安全性を確保できます。.tsd.tsdeclaring

于 2016-04-19T21:05:07.373 に答える
7

TSdeclareとの違い:interface

宣言する:

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

上記のコードdeclareで、TSコンパイラはクラスExampleがどこかで宣言されていることを認識します。これは、クラスが魔法のように含まれていることを意味するものではありません。declareプログラマーとしてのあなたは、(キーワードを使用して)宣言するときにクラスを使用可能にする責任があります。

インターフェース:

interface Example {
    Method(): void;
}

Aninterfaceは、typescript内にのみ存在する仮想構造です。typescriptコンパイラは、型チェックの唯一の目的でそれを使用します。コードがjavascriptにコンパイルされると、この構成全体が削除されます。typescriptコンパイラは、オブジェクトが正しい構造を持っているかどうかをチェックするためにインターフェイスを使用します。

たとえば、次のインターフェイスがある場合:

interface test {
  foo: number,
  bar: string,
}

このインターフェースタイプを持つ定義するオブジェクトは、インターフェースと正確に一致する必要があります。

// perfect match has all the properties with the right types, TS compiler will not complain.
  const obj1: test = {   
    foo: 5,
    bar: 'hey',
  }
于 2018-11-21T14:22:22.333 に答える