「宣言クラスのアクションのエクスポート」で「宣言」は何をしますか?


回答:


212

私が探していたものが見つかりました:

varと宣言

var新しい変数を作成します。declare変数が他の場所で作成されたことをTypeScriptに伝えるために使用されます。を使用する場合declare、生成されるJavaScriptには何も追加されません。これは単にコンパイラーへのヒントです。

たとえば、を定義する外部スクリプトを使用する場合var externalModule、既に設定されているdeclare var externalModuleTypeScriptコンパイラにヒントを与えるために使用しますexternalModule


externalModule他の変数を定義する外部JSを使用した同様のシナリオがあります。がexternalModule実行時に定義されていない理由は何ですか?他の変数のいくつかはそうではありませんか?
— アレハンドロゴンサレス

94

これを理解するには、まず「宣言」キーワードを理解する必要があります。

Gil Finkのブログからのよい説明はここにあります:

TypeScript declareキーワードは、TypeScriptファイルに由来しない可能性がある変数を宣言するために使用されます。

たとえば、TypeScript宣言ファイルを持たないmyLibraryというライブラリがあり、グローバル名前空間にmyLibraryという名前の名前空間があるとします。TypeScriptコードでそのライブラリを使用する場合は、次のコードを使用できます。

declare var myLibrary;

TypeScriptランタイムがmyLibrary変数に与える型は、any型です。ここでの問題は、設計時にその変数のIntellisenseがなくても、コードでライブラリを使用できることです。declareキーワードを使用せずに同じ動作をさせる別のオプションは、anyタイプの変数を使用することです。

var myLibrary: any;

どちらのコード例でも同じJavaScript出力になりますが、宣言例は読みやすく、アンビエント宣言を表現しています。


したがって、「宣言」キーワードを理解したら、どこにでも戻って

export declare class Action{
...
}

クラスの実際の実装はおそらくどこか別の場所にあるでしょう。おそらく.jsファイルでしょう。


2
事実ではない、「コードの例はどちらも同じJavaScriptの出力になります」:declare var myLibrary何もtranspileます:typescriptlang.org/play/#code/...
— アポロ

38

declare typescript:

declaretypescript のキーワードは、宣言が別の場所(外部javascriptファイルまたはランタイム環境の一部で記述された場所)で定義されていることをtypescriptコンパイラに伝えるのに役立ちます。

fooという変数がどこかで宣言されているとしましょう。その後、変数を参照しようとすると、typescriptコンパイラはエラーをスローします。

foo = 'random'; // Error: 'foo' is not defined

この問題は、次のdeclareキーワードを使用して修正できます。

declare var foo: string;
foo = 'random';  // no error anymore

これには次のような影響があります。

  • ときは、foo実際にはどこにも宣言されていない、と私たちは、ランタイムエラーが発生する可能性のある変数を使用してみてください。したがってdeclare、この時点で変数が使用可能であることがわかっている場合にのみ、キーワードを使用してください。
  • タイプを知っているので、(潜在的に)IDE Intellisenseにアクセスできます。
  • 型はわかっているので、typescriptコンパイラはコンパイル時に型をチェックし、特定のシナリオで間違った型を使用している場合に警告することができます。

18

この特定のケースでの宣言キーワード:

export declare class Actions {
    ...
}

...明らかに役に立たないので、TypeScriptはこれをエラーにすることを検討する必要があると思います(隠された理由があるかどうかはわかりません)。クラスを宣言する場合、それをインポートする必要はありません。誰かがそれをインポートすることを期待してクラスをエクスポートする場合、それを宣言する必要はありません。また、このクラスを宣言しているため、定義により、このクラスはインポートしなくても使用できるはずです。ただし、クラス宣言をエクスポートする場合は、これは当てはまりません。使用するにはインポートする必要があります。

TL; DR

export declare class Actions {
    ...
}

と同じです

declare class Actions {
    ...
}

私はそれらが同じだとは思いません、前者はで使用する必要がありますがimport、後者はそうではありません
— Ian Zhong

10

declare -インポートまたはエクスポートキーワードなし-TypeScriptによって自動的に選択される宣言ファイルを定義します。これは、レガシーモジュール(TypeScript定義なしのnpmインストールパッケージ)にタイピングを追加するのに役立つ機能です。

import/ exportはモジュールを使用するための適切な方法であり、すべてを手動で(そして私は少々手間がかかると思いますが)インポートする必要があります。ロジックでも定義でもインポートする必要があります。

実用的な使用例として、export declareすべてのサブエレメントのエクスポートを回避できます。例:

export declare namespace Redux {
    namespace Store {
        interface Definition { ... }
    }
}

次のものより読みやすいかもしれません:

export namespace Redux {
    export namespace Store {
        export interface Definition { ... }
    }
}

外部インポートはどちらの場合も同じです(例: import { Redux } from 'definitions/redux';:)。これは良い習慣かどうかはわかりませんが、きちんと整えられています!^^

ファイルにimportまたはexportを追加すると、ファイルがモジュールに昇格するため、declareスコープがグローバルレベルではなくなることに注意してください。

PS、バグがあります(問題16671):const enum宣言で使用し(私はreduxアクションタイプに対してそれを行います)、transpileOnlyフラグを指定した場合(create-react-app-typescriptパッケージがそうである、それが私が知っている理由です)、列挙型はインライン化されません!あなたはそれを実行するかもしれませんし、そうでないかもしれませんが、事前に知っておくと役に立ちます!


モジュールala内の名前空間は良い考えでexport namespaceはなく、不必要な名前空間を追加します。に関してはexport declare、AndréPenaの回答をご覧ください。
— ford04
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.