#TypeScript モジュール

導入

import または export ステートメントを含むファイルはすべてモジュールです。同様に、ファイルにエクスポート ステートメントが含まれていない場合、それはグローバル スクリプト ファイルです。

モジュール自体はスコープであり、グローバル スコープには属しません。モジュール内の変数、関数、クラスは内部でのみ表示され、モジュールの外部では表示されません。外部に公開されるインターフェイスは、export コマンドを使用して宣言する必要があります。他のファイルがモジュールのインターフェイスを使用する場合は、import コマンドを使用して入力する必要があります。

ファイルにエクスポート ステートメントが含まれていないが、それをモジュールとして扱いたい場合 (つまり、内部変数が外部から見えない場合)、スクリプトの先頭に行を追加できます。

輸出 {};

上記のステートメント行には実際の効果はありませんが、現在のファイルがモジュールとして扱われ、そのすべてのコードが内部コードになります。

ES モジュールの詳細については、ES6 チュートリアルを参照してください。ここでは繰り返しません。この章では主にTypeScriptモジュールの処理について紹介します。

TypeScript モジュールは、すべての ES モジュール構文をサポートすることに加えて、出力型と入力型を許可するという点でも独特です。

エクスポートタイプ ブール値 = true | false;

上記の例では、現在のスクリプトは型エイリアス Bool を出力します。このステートメント行は、型定義とインターフェイス出力を 1 行に記述するか、2 行に記述することもできます。

ブール型 = true | false;

エクスポート { ブール値 };

上記のモジュール ファイルが a.ts であるとすると、別のファイル b.ts は import ステートメントを使用してこの型に入ることができます。

import { Bool } から './a';

foo:Bool = true にします。

上記の例では、import ステートメントは型をロードします。ロードファイルは ./a として記述され、スクリプトファイルのサフィックス名は記述されないことに注意してください。 TypeScript を使用すると、モジュールをロードするときにモジュール ファイルのサフィックスを省略でき、./a から ./a.ts までが自動的に検索されます。

コンパイル時、2 つのスクリプトを同時にコンパイルできます。

$ tsc a.ts b.ts

上記のコマンドは、「a.ts」と「b.ts」をそれぞれ「a.js」と「b.js」にコンパイルします。

また、単に「b.ts」をコンパイルすることもできます。これはエントリ スクリプトであるため、tsc は依存するすべてのスクリプトを自動的にコンパイルします。

$ tsc b.ts

上記のコマンドは、b.tsa.ts に依存していることを検出し、自動的に a.ts を見つけて同時にコンパイルします。そのため、コンパイルされた製品は依然として 2 つのファイル a.js になります。 b.js

インポートタイプステートメント

import は、1 つのステートメントに型と通常のインターフェイスの両方を入力できます。

// a.ts
エクスポートインターフェイス A {
  foo: 文字列;
}

エクスポート a = 123;

//b.ts
import { A, a } from './a';

上記の例では、ファイル「a.ts」のexportステートメントはタイプ「A」と通常のインターフェース「a」を出力し、別のファイル「b.ts」は同じステートメントでタイプと通常のインターフェースを入力します。

これは型を通常のインターフェイスから区別するのに役立たないため、混乱を引き起こしやすくなります。この問題を解決するために、TypeScript では 2 つの解決策が導入されています。

1 つ目の方法は、import ステートメントに入力したタイプの前に type キーワードを追加することです。

import { type A, a } from './a';

上の例では、import ステートメントに入力された型 A の前に、それが型であることを示す type キーワードが付いています。

2 番目の方法は、import type ステートメントを使用する方法です。このステートメントは、通常のインターフェイスではなく、タイプを入力するためにのみ使用されます。

// 正しい
タイプ { A } を './a' からインポートします。
b:A = 'こんにちは' とします。

// エラーを報告する
タイプ { a } を './a' からインポートします。
b = a とします。

上記の例では、インポート タイプの入力型 A は正しく、A を型として使用できます。ただし、通常のインターフェイス「a」を入力し、値として「a」を使用すると、エラーが報告されます。つまり、「import type」が表示されると、入力するタイプが次のとおりである必要があることがわかります。

import type ステートメントでは、デフォルトのタイプをインポートすることもできます。

'moduleA' からタイプ DefaultType をインポートします。

import type ネームスペースにおいて、すべての型をインポートする書き方は以下のとおりです。

type * を「moduleA」から TypeNS としてインポートします。

同様に、export ステートメントにも 2 つのメソッドがあり、出力のタイプを示します。

タイプ A = 'a';
タイプ B = 'b';

//方法1
エクスポート {タイプ A、タイプ B};

//方法2
エクスポートタイプ {A, B};

上記の例では、最初の方法は、出力がタイプであることを示す type キーワードをプレフィックスとして使用することであり、2 番目の方法は、行全体がタイプとして出力されることを示す、export type ステートメントを使用することです。 。

以下は、クラスを型としてエクスポートするエクスポート型の例です。

クラスポイント{
  x: 数値。
  y:数値;
}

エクスポート タイプ { ポイント };

上記の例では、export type ステートメントを使用しているため、出力は Point クラスではなく、Point によって表されるインスタンス タイプになります。入力する場合はタイプのみ入力可能です。

'./module' からタイプ { ポイント } をインポートします。

const p:Point = { x: 0, y: 0 };

上記の例では、「Point」は型入力としてのみ使用でき、通常のインターフェースとしては使用できません。

importsNotusedAsValues コンパイル設定

TypeScript を JavaScript にコンパイルするときに、TypeScript の独自の入力型 (type) import ステートメントを処理するにはどうすればよいですか?

TypeScript には importsNotusedAsValues コンパイル設定が用意されており、これには 3 つの可能な値があります。

(1) remove: これはデフォルト値で、入力タイプの import ステートメントを自動的に削除します。

(2)preserve: 入力型のインポート文を保存します。

(3) error: 入力型の import ステートメントを保持します (preserve と同じ)。ただし、import type の形式で記述する必要があります。そうしないとエラーが報告されます。

例を見ると、以下は入力タイプの import ステートメントです。

import { TypeA } から './a';

上の例では、「TypeA」が型です。

remove のコンパイル結果により、このステートメントは削除されます。

「preserve」のコンパイル結果はステートメントは保持しますが、型に関わる部分は削除されます。

インポート './a';

上記は preserve のコンパイル結果です。コンパイルされた import ステートメントは a.js からインターフェイス (型を含む) をインポートしませんが、a.js の実行をトリガーすることがわかります。したがって、「a は .js に保持されます」。

error のコンパイル結果は preserve と同じですが、入力型の import ステートメントを import type の形式で記述する必要があるため、コンパイル処理中にエラーが報告されます。元のステートメントを次の形式に変更しても、エラーは報告されません。

タイプ { TypeA } を './a' からインポートします。

CommonJS モジュール

CommonJS は Node.js の独自のモジュール形式であり、ES モジュール形式と互換性がありません。

import = ステートメント

TypeScript は、「import =」ステートメントを使用して CommonJS モジュールをインポートします。

import fs = require('fs');
const code = fs.readFileSync('hello.ts', 'utf8');

上記の例では、CommonJS モジュールは import = ステートメントと require() コマンドを使用してインポートされます。モジュール自体の使い方はNode.jsと同じです。

TypeScript では、import = ステートメントの使用に加えて、import * as [インターフェイス名] from "モジュール ファイル" を使用して CommonJS モジュールをインポートすることもできます。

import * as fs from 'fs';
// と同等
import fs = require('fs');

エクスポート = ステートメント

TypeScript は、export = ステートメントを使用して CommonJS モジュールのオブジェクトを出力します。これは CommonJS の module.exports オブジェクトと同等です。

obj = { foo: 123 };

エクスポート = オブジェクト;

「export =」ステートメントによって出力されたオブジェクトは、「import =」ステートメントを使用してのみロードできます。

import obj = require('./a');

コンソール.log(obj.foo); // 123

モジュールの配置

モジュール解決とは、インポート ステートメントおよびエクスポート ステートメント内のモジュール ファイルの場所を決定するために使用されるアルゴリズムを指します。

// 相対モジュール
import { TypeA } から './a';

// 非相対モジュール
import * as $ from "jquery";

上記の例では、TypeScript はどのモジュール ./a または jquery を参照しているのか、またその特定の場所をどのように決定するのでしょうか。使用されるアルゴリズムは「モジュール位置決め」と呼ばれます。

コンパイル パラメータ moduleResolution は、どの位置決めアルゴリズムが使用されるかを指定するために使用されます。よく使用されるアルゴリズムには、「Classic」と「Node」の 2 つがあります。

moduleResolution が指定されていない場合、そのデフォルト値はコンパイル パラメータ module に関連します。 modulecommonjs に設定されている場合 (プロジェクト スクリプトは CommonJS モジュール形式を採用しています)、moduleResolution のデフォルト値は Node であり、Node.js のモジュール配置アルゴリズムを使用します。他の場合 (「モジュール」が es2015、esnext、amd、system、umd などに設定されている場合)、「クラシック」位置決めアルゴリズムが使用されます。

相対モジュール、非相対モジュール

モジュールをロードする場合、対象モジュールは相対モジュール(相対インポート)と非相対モジュール(非相対インポート)の 2 種類に分けられます。

相対モジュールとは、パスが /./../ で始まるモジュールを指します。以下の import ステートメントによってロードされるモジュールはすべて相対モジュールです。

  • 「./components/Entry」からエントリをインポートします;
  • 「../constants/http」から { DefaultHeaders } をインポートします;
  • インポート "/mod";

モジュールの相対位置は、現在のスクリプトの位置に基づいて計算され、通常は現在のプロジェクト ディレクトリ構造に保存されたモジュール スクリプトに使用されます。

非相対モジュールとは、パス情報のないモジュールを指します。以下の import ステートメントによってロードされるモジュールはすべて非相対モジュールです。

  • import * as $ from "jquery";
  • 「@angular/core」から { コンポーネント } をインポートします;

非相対モジュールの位置は、baseUrl 属性またはモジュール マッピングによって決定され、通常は外部モジュールをロードするために使用されます。

古典的な方法

クラシックな方法では、現在のスクリプトのパスを「ベース パス」として使用して、モジュールの相対位置を計算します。たとえば、スクリプト a.ts にコード行 import { b } from "./b" が含まれている場合、TypeScript は a.tsb.d.ts をディレクトリ内で検索します。 ts` があります。

非相対モジュールの場合、現在のスクリプトのパスは、上位ディレクトリを階層ごとに検索する開始点としても使用されます。たとえば、スクリプト「a.ts」に「import { b } from "b"」というコード行がある場合、「b.ts」と「b.d.ts」がそれぞれの上位ディレクトリで検索されます。振り向く。

ノードメソッド

NodeメソッドはNode.jsのモジュールロードメソッドをシミュレートするもので、require()の実装メソッドです。

相対モジュールは、現在のスクリプトのパスを「ベース パス」として引き続き使用します。たとえば、スクリプト ファイル a.tslet x = require("./b"); というコード行がある場合、TypeScript は次の順序で検索します。

  1. 現在のディレクトリに b.tsb.tsxb.d.ts が含まれているかどうか。存在しない場合は、次のステップに進みます。
  2. 現在のディレクトリにサブディレクトリ b があるかどうか、またサブディレクトリ内の package.json ファイルにモジュール エントリ ファイルを指定する types フィールドがあるかどうか。存在しない場合は、次のステップに進みます。
  3. 現在のディレクトリのサブディレクトリ bindex.tsindex.tsxindex.d.ts が含まれているかどうか。存在しない場合は、エラーが報告されます。

非相対モジュールは、現在のスクリプトのパスを開始点として使用し、上位ディレクトリを参照してサブディレクトリ node_modules があるかどうかを確認します。たとえば、スクリプト ファイル「a.js」に「let x = require("b");」という行がある場合、TypeScript は次の順序で検索します。

  1. 現在のディレクトリのサブディレクトリ node_modulesb.tsb.tsxb.d.ts が含まれているかどうか。
  2. ファイル package.json が現在のディレクトリのサブディレクトリ node_modules に存在するかどうかを確認し、ファイルの types フィールドにエントリ ファイルが指定されているかどうかを確認します。存在する場合は、ファイルをロードします。
  3. 現在のディレクトリのサブディレクトリ node_modules にサブディレクトリ @types が含まれているかどうかを確認し、ディレクトリ内でファイル b.d.ts を検索します。
  4. 現在のディレクトリのサブディレクトリ node_modules にサブディレクトリ b が含まれているかどうかを確認し、ディレクトリ内で index.tsindex.tsx、および index.d.ts を検索します。
  5. 上位ディレクトリに入り、見つかるまで上記の 4 つの手順を繰り返します。

パスマッピング

TypeScript を使用すると、開発者は「tsconfig.json」ファイルでスクリプト モジュールへのパスを手動で指定できます。

(1)ベースURL

「baseUrl」フィールドを使用すると、スクリプト モジュールのベース ディレクトリを手動で指定できます。

{
  "コンパイラーオプション": {
    "baseUrl": "."
  }
}

上記の例では、baseUrl はドットであり、ベース ディレクトリが tsconfig.json が配置されているディレクトリであることを示しています。

(2)パス

「paths」フィールドは、モジュールおよび実際のスクリプトへの非相対パスのマッピングを指定します。

{
  "コンパイラーオプション": {
    "baseUrl": ".",
    「パス」: {
      "jquery": ["node_modules/jquery/dist/jquery"]
    }
  }
}

上記の例では、モジュール「jquery」をロードするときに、実際にロードされるスクリプトは「node_modules/jquery/dist/jquery」であり、その位置は「baseUrl」フィールドに基づいて計算されます。

上記の例の jquery 属性の値は配列であり、複数のパスを指定できることに注意してください。最初のスクリプト パスが存在しない場合は、2 番目のパスがロードされ、以下同様に続きます。

(3)rootDirs

「rootDirs」フィールドは、モジュールを見つけるときに検索する必要がある追加のディレクトリを指定します。

{
  "コンパイラーオプション": {
    "rootDirs": ["src/zh", "src/de", "src/#{locale}"]
  }
}

上の例では、「rootDirs」は、モジュールを見つけるときに検索する必要があるさまざまな国際化ディレクトリを指定します。

tsc の --traceResolution パラメータ

モジュールの配置プロセスは複雑であるため、tsc コマンドには「--traceResolution」パラメータがあり、コンパイル中にコマンド ラインでモジュールの配置の各ステップを表示できます。

$ tsc --traceResolution

上記例では、traceResolutionでモジュールの配置判定処理を出力します。

tsc の --noResolve パラメータ

tsc コマンドの --noResolve パラメータは、モジュールを配置するときにコマンド ラインで渡されたモジュールのみが考慮されることを示します。

たとえば、「app.ts」には次の 2 行のコードが含まれています。

import * as A from "moduleA";
import * as B from "moduleB";

次のコマンドを使用してコンパイルします。

$ tsc app.ts moduleA.ts --noResolve

上記のコマンドは --noResolve パラメータを使用しているため、コマンドラインから渡されるため moduleA.ts を見つけることができますが、渡されないため moduleB を見つけることができないため、エラーが報告されます。 。

参考リンク


作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0