Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

TypeScript Modules: import, export and Type-Only Imports

What Modules Solve

A TypeScript module is a file that exports or imports something. Modules keep code organized by giving each file a clear responsibility and by making dependencies explicit.

Without modules, large projects quickly become difficult to navigate. With modules, utilities, models, services, components, and API clients can live in separate files while still working together through imports and exports.

TypeScript modules use JavaScript module syntax. TypeScript adds type checking, type-only imports, and compiler settings that control how modules are resolved and emitted.

Named Exports
export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

export const TAX_RATE = 0.18;

Named Exports

Named exports are explicit and easy to search. A file can export many named values, and importers choose exactly what they need.

Named exports are usually a strong default for utilities, constants, shared models, service functions, and feature helpers because refactors are clearer and accidental name changes are easier to catch.

Import Named Values
import { add, TAX_RATE } from "./math";

export function calculateInvoice(subtotal: number): number {
  const tax = subtotal * TAX_RATE;
  return add(subtotal, tax);
}

Default Exports

A default export represents the main value from a file. Default exports are common for page components, one primary class, or a module that naturally exposes one main thing.

Use default exports intentionally. In larger shared utility files, named exports are often easier to maintain because every imported name is tied to the exported name.

Export StyleCommon Use
Named exportUtilities, constants, models, multiple public values.
Default exportOne main component, class, or service from a file.
Mixed exportsUse carefully so the file API stays obvious.
Default Export
export default class UserService {
  findName(id: number): string {
    return id === 1 ? "Admin" : "Guest";
  }
}

// app.ts
import UserService from "./UserService";

const service = new UserService();
console.log(service.findName(1));

Importing Types Separately

import type imports only type information. The import is erased from compiled JavaScript because interfaces and type aliases do not exist at runtime.

Using import type makes intent clear and can avoid build problems in projects that enforce isolated modules or strict module syntax. It also helps developers see which dependencies are runtime dependencies and which are only for checking.

Type-Only Import
import { calculateInvoice } from "./billing";
import type { User } from "./types";

const user: User = {
  id: 1,
  name: "Admin",
};

console.log(user.name, calculateInvoice(1000));

Re-exporting from an Index File

A feature folder may contain several files. An index.ts file can re-export the public pieces so other parts of the app import from one stable path.

Use this carefully. Re-exporting everything from everywhere can create confusing dependency graphs. Export only the API that other folders should depend on.

Barrel Export
export type { User, UserRole } from "./user.types";
export { createUserService } from "./user.service";
export { validateUserInput } from "./user.validation";

Path Aliases

Path aliases make imports shorter and more stable. Instead of importing from ../../../services/users, a project might use @/services/users.

Aliases are usually configured in tsconfig.json and must also be understood by the bundler or runtime. TypeScript can type-check an alias, but the tool that runs the code must know how to resolve it too.

Alias Import
import { createUserService } from "@/features/users";
import type { User } from "@/features/users";

export async function loadProfile(id: number): Promise<User | null> {
  const service = createUserService();
  return service.findById(id);
}

Module Boundaries

Good modules have clear ownership. A feature module should expose what other parts of the app need and keep internal helpers private. This prevents unrelated code from depending on implementation details.

If a shared folder becomes a dumping ground, it becomes hard to understand. Prefer specific shared modules such as date, money, http, or validation over vague folders like misc.

Module ChoiceEffect
Small focused fileEasy to test and reuse.
Feature index fileClean public imports for a folder.
Deep private importCan create fragile dependencies.
Circular importCan cause confusing runtime behavior.

Common Module Mistakes

Most module problems come from unclear ownership. A shared folder should not become a dumping ground, and feature modules should avoid reaching deeply into each other’s private files.

Keep imports pointed at public entry points when possible. If a file is imported from many unrelated places, it may belong in a shared utility package or it may need a clearer abstraction.

  • Do not mix default and named exports in the same file unless there is a clear reason.
  • Avoid long relative paths such as ../../../utils by organizing modules or using configured path aliases.
  • Use import type for interfaces and aliases that are only needed for checking.
  • Keep feature internals private by exporting only the pieces other modules should use.
  • Avoid circular imports by moving shared contracts into smaller neutral modules.
Key Takeaways
  • TypeScript modules build on JavaScript import/export syntax.
  • Value imports become runtime JavaScript.
  • import type is erased from JavaScript output.
  • Index files can expose a clean public API for a folder.
  • Path aliases need support from TypeScript and the runtime or bundler.
  • Good module boundaries make large TypeScript projects easier to maintain.

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.