TypeScript Tutorial: Modules & Namespaces
Organize TypeScript code with ES modules, export patterns, and declaration files.
ES Module Syntax
TypeScript uses the same `import`/`export` syntax as modern JavaScript:
```typescript
// math.ts — named exports
export function add(a: number, b: number): number {
return a + b;
}
export const PI = 3.14159;
export interface Vector {
x: number;
y: number;
}
// main.ts — named imports
import { add, PI, Vector } from "./math";
```
---
Default Export
```typescript
// logger.ts
export default function log(msg: string): void {
console.log(`[LOG] ${msg}`);
}
// main.ts
import log from "./logger";
log("Server started");
```
---
Re-exporting
```typescript
// index.ts — barrel file
export { add, PI } from "./math";
export { default as log } from "./logger";
export type { Vector } from "./math";
```
---
Type-only Imports
Avoid importing runtime code just for types:
```typescript
import type { User } from "./types"; // erased at compile time
import { createUser } from "./users"; // kept in output
```
---
Declaration Files (.d.ts)
For libraries without TypeScript support, declaration files describe the API:
```typescript
// lodash.d.ts (simplified)
declare module "lodash" {
export function chunk<T>(arr: T[], size: number): T[][];
export function flatten<T>(arr: T[][]): T[];
}
```
Most popular packages include `.d.ts` files or have `@types/package-name` on npm.
---
What's Next?
Next: **Advanced Types** — mapped types, conditional types, and template literal types.
What you'll learn in this TypeScript modules & namespaces tutorial
This interactive TypeScript tutorial has 12 hands-on exercises. Estimated time: 10 minutes.
- Named exports — share specific values — Named exports let you export specific names from a module. Callers import only what they need.
- Type exports — share type definitions — Type-only exports (`export type`) are erased at compile time — they produce no JavaScript output. Use `import type` to i…
- Re-exporting — barrel files — A barrel file (`index.ts`) re-exports from multiple modules, giving callers a single clean import path.
- Namespace imports — import everything — `import * as name` imports all named exports into a namespace object. Useful when a module has many related exports you …
- Dynamic imports — lazy loading — Dynamic `import()` loads a module on demand instead of at startup. This reduces initial bundle size and enables code spl…
- Module augmentation — extend third-party types — Module augmentation lets you add to an existing module's types. This is how you add custom properties to Express's `Requ…
- Declaration merging — extend interfaces — TypeScript merges multiple interface declarations with the same name. This is how the DOM types are built — browser APIs…
- ESM vs CommonJS — module systems — TypeScript supports both ES Modules (import/export) and CommonJS (require/module.exports). Understanding the difference …
- Circular dependencies — detecting and avoiding — Circular imports occur when module A imports from module B, and module B imports from module A. TypeScript handles them …
- Path aliases — clean import paths — TypeScript path aliases let you import with clean paths like `@/components/Button` instead of `../../../components/Butto…
- Conditional module loading — environment-specific code — Sometimes you want different implementations for different environments (browser vs Node.js). TypeScript can handle this…
- Strict mode — maximum type safety — TypeScript's `strict` mode enables the strongest type checking. Understanding what it enables helps you write safer code…
TypeScript Modules & Namespaces concepts covered
- ES Module Syntax
- Default Export
- Re-exporting
- Type-only Imports
- Declaration Files (.d.ts)
- What's Next?