7.1 import宣言とexport宣言
プログラムが大きくなると、機能やデータごとにファイルを分割して管理する「モジュールシステム」が不可欠になります。この節では、モジュール間でデータを受け渡すための基本的な構文を学習します。
7.1.1 変数のエクスポートとインポート
Section titled “7.1.1 変数のエクスポートとインポート”モジュール内の変数や関数を他のファイルから使えるようにするのが export で、他から取り込むのが import です。
- エクスポート: 変数宣言の前に
exportを付けます(例:export const name = "uhyo";)。または、ファイル内で宣言済みの変数をまとめてexport { name, age };と記述することもできます。 - インポート:
import { 変数名 } from "./ファイル名.js";のように記述します。TypeScriptファイル(.ts)であっても、コンパイル後の環境(Node.jsなど)の制約により、インポート時の拡張子は.jsを指定するのが一般的です。 - 名前の変更 (as):
export { name as uhyoName }やimport { age as uhyoAge }のように、asを使って外側に見せる名前や受け取る側の変数名を変更できます。
7.1.2 関数もエクスポートできる
Section titled “7.1.2 関数もエクスポートできる”データの変数だけでなく、機能を提供する「関数」もエクスポート可能です。
- 構文: アロー関数を代入する変数に対して
export const getUhyoName = () => { ... }とするか、関数宣言に対してexport function getUhyoName() { ... }と記述します。クラスの場合もexport class ClassName { ... }となります。
コラム31 モジュールとカプセル化
Section titled “コラム31 モジュールとカプセル化”モジュールシステムは、データを隠蔽する「カプセル化」の手段として非常に有効です。
モジュール内で let や const で宣言された変数は、export しない限り外部のファイルからは絶対に読み書きできません。そのため、「内部状態(カウンタの値など)は隠蔽し、それを操作する関数だけをエクスポートする」という設計が容易に実現できます。
コラム32 モジュールの実体は1つ
Section titled “コラム32 モジュールの実体は1つ”あるモジュールが複数の別のファイルからインポートされたとしても、そのモジュールが評価・実行されるのはプログラム全体で「1回だけ」です。したがって、モジュール内の内部状態(変数)はすべてのインポート元で共有されます。
7.1.3 defaultエクスポートとdefaultインポート
Section titled “7.1.3 defaultエクスポートとdefaultインポート”モジュールから「代表的な値」を1つだけエクスポートするための特殊な構文です。
- エクスポート:
export default 式;またはexport default function ...と記述します。 - インポート:
import 任意の変数名 from "./module.js";のように、{}で囲まずに、受け取る側が自由な名前をつけてインポートします。 - 実態: 内部的には
defaultという名前で変数をエクスポート/インポートしているのと同じ扱いです。
コラム33 defaultエクスポートは使わないほうがよい?
Section titled “コラム33 defaultエクスポートは使わないほうがよい?”TypeScript開発において、export default の使用は避けた方がよいという意見が一定の支持を集めています。
理由は、エクスポートされた名前が明示されていないため、IDE(VS Codeなど)の「自動インポート(入力補完)」機能がうまく働かないケースが多いためです。通常の export を使い、インポート時にそのまま使える明確な名前を付けるのが推奨されます。
7.1.4 型のインポート・エクスポート
Section titled “7.1.4 型のインポート・エクスポート”TypeScript特有の機能として、「型」もモジュール間でやり取りできます。
- エクスポート:
export type Animal = { ... }のように型宣言にexportを付けます。 - 明示的な型のインポート:
import type { Animal } from "./animal.js";のようにtypeを指定すると、インポートしたものは「型」としてのみ使用可能となり、値としては使えなくなります。import { tama, type Animal } from "./animal.js";のように、1つのimport宣言の中で変数と型を混在させる構文(Inline type imports)も最近のバージョンで導入され便利になっています。
- 意義: TypeScriptコンパイラ以外のツール(Babelやesbuildなど)でビルドする際、「これは型なのでJavaScriptへの変換時に削除してよい」とツール側に明示的に伝えるために役立ちます。
7.1.5 その他の関連構文
Section titled “7.1.5 その他の関連構文”- 一括インポート:
import * as uhyo from "./uhyo.js";とすると、そのモジュールからエクスポートされたすべての変数をプロパティに持つ「モジュール名前空間オブジェクト」が変数uhyoに代入されます(uhyo.nameのようにアクセスします)。 - 再エクスポート:
export { name } from "./uhyo.js";のように記述すると、別のモジュールからインポートしたものを、自ファイルを経由させずにそのまま外部へ公開できます(バレルファイルの作成などに使用します)。
コラム34 スクリプトとモジュール
Section titled “コラム34 スクリプトとモジュール”TypeScript(およびJavaScript)のファイルは、「スクリプト」と「モジュール」の2種類に分類されます。
- ファイル内に
importやexportが一つでも含まれていれば「モジュール」として扱われ、変数のスコープはそのファイル内に閉じます。 - これらが含まれない「スクリプト」の場合、変数のスコープはプロジェクト全体(グローバル)に広がってしまいます。TypeScript開発では、空のファイルであっても
export {};と書いて明示的にモジュール化するのが一般的です。
コラム35 ES Modules
Section titled “コラム35 ES Modules”本節で解説した import / export の仕組みは、ECMAScript標準のモジュールシステムであるため ES Modules (ESM) と呼ばれます。これ以前は、Node.jsの世界で広く使われていた独自の CommonJS (require や module.exports を使用)という仕組みが主流でした。