Modules
## Learning Objectives
- Export and import modules
- Use named and default exports
- Work with namespaces
- Understand module resolution
- Configure TypeScript for modules
## JavaScript Modules
### ES Module Syntax
```typescript
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
export const PI = 3.14159;
```
```typescript
// main.ts
import { add, PI } from "./math";
console.log(add(2, 3)); // 5
console.log(PI); // 3.14159
```
## Named Exports
### Individual Exports
```typescript
// validators.ts
export const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
export function isEmail(value: string): boolean {
return emailRegex.test(value);
}
```
### Import Specific
```typescript
import { isEmail } from "./validators";
if (isEmail("test@example.com")) {
console.log("Valid email");
}
```
### Rename on Export
```typescript
export { isEmail as validateEmail };
```
### Rename on Import
```typescript
import { validateEmail as checkEmail } from "./validators";
```
## Default Exports
### Declaration
```typescript
// logger.ts
export default class Logger {
log(message: string): void {
console.log(`[LOG] ${message}`);
}
}
```
### Import
```typescript
import Logger from "./logger";
let logger = new Logger();
logger.log("Hello!");
```
### Function Default Export
```typescript
// add.ts
export default function add(a: number, b: number): number {
return a + b;
}
```
```typescript
import add from "./add";
console.log(add(2, 3)); // 5
```
## Namespace Exports
### export = syntax
```typescript
// math.ts
export = class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
```
```typescript
// main.ts
import Calculator = require("./math");
let calc = new Calculator();
calc.add(2, 3);
```
## Re-exporting
### From Another Module
```typescript
// index.ts
export { add, subtract } from "./math";
export { isEmail } from "./validators";
```
### All as Namespace
```typescript
export * from "./math";
export * from "./validators";
```
## Import Types
### Type-only Import
```typescript
import type { User } from "./types";
// User is only used as a type
function createUser(data: User): User {
return { ...data };
}
```
### Inline Type Import
```typescript
import { User, type Admin } from "./types";
```
## Dynamic Imports
### As Function
```typescript
async function loadModule() {
const module = await import("./math");
console.log(module.add(2, 3));
}
```
### For Code Splitting
```typescript
async function loadFeature() {
if (needsAdvancedFeature()) {
const { advancedTool } = await import("./advanced");
advancedTool.run();
}
}
```
## CommonJS Modules
### Export
```typescript
// old-module.js (CommonJS style)
module.exports = {
add: (a: number, b: number) => a + b
};
```
### CommonJS Import
```typescript
import module = require("./old-module");
console.log(module.add(2, 3));
```
## Namespaces
### Namespace Declaration
```typescript
namespace Validation {
export interface StringValidator {
isValid(s: string): boolean;
}
export class EmailValidator implements StringValidator {
isValid(s: string): boolean {
return s.includes("@");
}
}
}
```
### Namespace Usage
```typescript
let validator: Validation.StringValidator = new Validation.EmailValidator();
```
## Namespace Files
### Multiple Files
```typescript
// validators.ts
namespace Validation {
export interface StringValidator {
isValid(s: string): boolean;
}
}
```
```typescript
// email-validator.ts
///
namespace Validation {
export class EmailValidator implements StringValidator {
isValid(s: string): boolean {
return s.includes("@");
}
}
}
```
## Module Resolution
### relative vs Non-relative
```typescript
// Relative imports
import { User } from "./types"; // ./types.ts
import { Logger } from "../utils/logger";
// Non-relative imports
import { Component } from "react";
import { from } from "rxjs";
```
### Resolution Strategies
| Strategy | Description |
|----------|-------------|
| node | Node.js CommonJS |
| node16 | Node.js ESM with package.json "type": "module" |
| nodenext | Latest Node.js ESM |
## tsconfig.json Settings
### Module Configuration
```json
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
}
}
```
### ESM Interop
```json
{
"compilerOptions": {
"esModuleInterop": true
}
}
```
This enables:
- `import React from "react"` works even if React uses CommonJS
- `export =` syntax works with ES imports
## Importing JSON
### With resolveJsonModule
```typescript
// tsconfig.json
{
"compilerOptions": {
"resolveJsonModule": true
}
}
```
```typescript
// data.json
{
"name": "Alice",
"age": 30
}
```
```typescript
import data from "./data.json";
console.log(data.name); // "Alice"
```
## Ambient Modules
### Ambient Module Declaration
```typescript
// third-party.d.ts
declare module "my-library" {
export function doSomething(): void;
}
```
### Ambient Module Usage
```typescript
import { doSomething } from "my-library";
doSomething();
```
## Barrel Exports
### index.ts Re-export
```typescript
// components/Button/index.ts
export { Button } from "./Button";
export { Card } from "./Card";
export { Input } from "./Input";
```
```typescript
// Usage
import { Button, Card } from "./components";
```
## Summary
- ES modules: `export` and `import`
- Named exports: `export const foo = ...`
- Default exports: `export default ...`
- Type-only imports: `import type { T }`
- Re-export: `export { foo } from "./bar"`
- Namespace: `namespace Name { ... }`
- Use `tsconfig.json` to configure modules
- Use barrel files (index.ts) for clean imports
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →