Programmingフロントエンド開発者 / フルスタック開発者

TypeScriptにおけるモジュールシステムはどのように機能し、JavaScriptのモジュールとは何が異なるのか?型宣言とTypeScriptのエクスポートの特徴は何か?

Hintsage AIアシスタントで面接を突破

回答

TypeScriptはJavaScriptの主要なモジュールシステムであるCommonJSとES Modulesの両方をサポートしており、コードを整理するためにimportexportのキーワードを使用することができます。TypeScriptの特徴は、値と同じようにエクスポートおよびインポートできる型宣言が存在することです。

たとえば、インターフェースをエクスポートできます:

// types.ts export interface User { id: number; name: string; } // index.ts import { User } from './types'; const u: User = { id: 1, name: 'Alice' };

また、export typeexport interfaceimport typeもサポートされており、これにより最終的なバンドルにコードを引き込むことなく、型のみをインポートすることができます。これによりビルドが最適化されます:

import type { User } from './types';

重要な特徴: TypeScriptでは、最終的なJavaScriptに含まれない型のみをエクスポートすることができます。

トリックの質問

import { SomeType } from './file'import type { SomeType } from './file'の違いは何か?

間違った回答: どちらも同じことを行います。

正しい回答: import { SomeType } ...は、型だけでもモジュール全体がインポートされ、結果としてJavaScriptに含まれる可能性があります。import type { SomeType } ...は、型のみがインポートされることを保証し、コンパイル時に副作用や出力のコードがないことを確実にします。

トピックの詳細を知らないことによる実際のエラーの例


物語

大規模プロジェクトでチームが副作用のあるモジュールからimport { SomeType } ...で型をインポートしました(たとえば、require/import時にコードを実行するもの)。その結果、プロダクションビルドに不要な依存関係と副作用が持ち込まれ、バグが発生し、バンドルのサイズが増加しました。


物語

開発者がグローバル変数を通じてグローバル型を記述することを決定し、型宣言ではなく、偶然に同じ名前の型と値をエクスポートしました。これにより、いくつかのファイルで名前の衝突が発生し、TypeScriptの更新後にビルドが失敗しました。


物語

チームはexport/import typeの特徴を区別せずに、データと一緒に型をエクスポートしました。その結果、tree-shakingツールが死んだコードを除外できず、バンドルが増加しました。