Skip to content

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 モジュールとカプセル化”

モジュールシステムは、データを隠蔽する「カプセル化」の手段として非常に有効です。 モジュール内で letconst で宣言された変数は、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への変換時に削除してよい」とツール側に明示的に伝えるために役立ちます。
  • 一括インポート: import * as uhyo from "./uhyo.js"; とすると、そのモジュールからエクスポートされたすべての変数をプロパティに持つ「モジュール名前空間オブジェクト」が変数 uhyo に代入されます(uhyo.name のようにアクセスします)。
  • 再エクスポート: export { name } from "./uhyo.js"; のように記述すると、別のモジュールからインポートしたものを、自ファイルを経由させずにそのまま外部へ公開できます(バレルファイルの作成などに使用します)。

コラム34 スクリプトとモジュール

Section titled “コラム34 スクリプトとモジュール”

TypeScript(およびJavaScript)のファイルは、「スクリプト」と「モジュール」の2種類に分類されます。

  • ファイル内に importexport が一つでも含まれていれば「モジュール」として扱われ、変数のスコープはそのファイル内に閉じます。
  • これらが含まれない「スクリプト」の場合、変数のスコープはプロジェクト全体(グローバル)に広がってしまいます。TypeScript開発では、空のファイルであっても export {}; と書いて明示的にモジュール化するのが一般的です。

本節で解説した import / export の仕組みは、ECMAScript標準のモジュールシステムであるため ES Modules (ESM) と呼ばれます。これ以前は、Node.jsの世界で広く使われていた独自の CommonJSrequiremodule.exports を使用)という仕組みが主流でした。