Modules and Namespaces
TypeScript uses the same ES module syntax as modern JavaScript. Modules keep code organized, testable, and reusable across files.
Named Exports
Export individual bindings from a file:
// math.ts
export const PI = 3.14159;
export function add(a: number, b: number): number {
return a + b;
}
export function multiply(a: number, b: number): number {
return a * b;
}
Import named exports:
// app.ts
import { PI, add, multiply } from './math.js';
console.log(PI); // 3.14159
console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20
Use .js extensions in import paths when targeting ES modules in Node.js — TypeScript resolves them to the corresponding .ts source files.
Default Exports
One default export per file:
// logger.ts
export default class Logger {
log(message: string): void {
console.log(`[LOG] ${message}`);
}
}
// main.ts
import Logger from './logger.js';
const logger = new Logger();
logger.log('Application started');
Prefer named exports for better refactoring and autocomplete. Default exports are common in React components.
Re-exports
Aggregate modules into a single entry point:
// utils/index.ts
export { add, multiply } from './math.js';
export { formatDate } from './date.js';
export type { User } from './types.js';
Consumers import from the barrel file:
import { add, formatDate } from './utils/index.js';
Type-Only Imports and Exports
Use import type and export type to strip types at compile time:
// types.ts
export interface User {
id: number;
name: string;
}
export type Role = 'admin' | 'user';
// user-service.ts
import type { User, Role } from './types.js';
export function createUser(name: string, role: Role): User {
return { id: Date.now(), name };
}
Type-only imports prevent accidental runtime dependencies on erased types.
Module Resolution
Configure how TypeScript resolves imports in tsconfig.json:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
Path aliases simplify imports:
import { User } from '@/models/user.js';
For Node.js without a bundler, use "moduleResolution": "NodeNext" and include file extensions in imports.
CommonJS Interop
When importing CommonJS modules in a TypeScript ES module project:
import express from 'express'; // requires "esModuleInterop": true
Enable "esModuleInterop": true in tsconfig.json for smoother default import syntax.
Prefer ES modules for new code. Next, we learn how to narrow types at runtime with type guards.