TypeScript Modules & Namespaces
Also Known As
TypeScript namespaces
module resolution
ambient module
declare module
TL;DR
ES modules (import/export) are the modern standard — namespaces are legacy for global scripts and ambient declarations only.
Explanation
TypeScript module: any file with an import or export statement — isolated scope, explicit dependencies. Namespace (formerly 'internal module'): namespace Foo {} — only appropriate for global script files and ambient declarations. Modern TypeScript: always prefer ES modules for better tree-shaking, tooling, and compatibility. Ambient modules: declare module 'lodash' for adding types to untyped JavaScript packages. Declaration merging: interfaces and namespaces can be merged to extend existing types.
Common Misconception
✗ TypeScript namespaces are the correct way to organise code — namespaces are a legacy pattern; ES modules with explicit imports provide better tree-shaking and tooling support.
Why It Matters
Using namespaces in a bundler project prevents tree-shaking (all namespace code is included even if unused) and creates confusion about what is exported — ES modules are the correct default.
Common Mistakes
- Using namespaces in modern bundled applications — use ES modules
- Forgetting that a .ts file without import/export is a global script, not a module
- Triple-slash references (/// <reference>) in module code — use import in modern TypeScript
- Mixing namespace and module patterns in the same codebase
Code Examples
✗ Vulnerable
// Legacy namespace — not tree-shakeable, pollutes global scope:
namespace MyApp {
export namespace Utils {
export function formatDate(date: Date): string {
return date.toISOString();
}
}
}
// Usage: MyApp.Utils.formatDate(new Date())
✓ Fixed
// ES Module — tree-shakeable, explicit dependencies:
// utils/date.ts:
export function formatDate(date: Date): string {
return date.toISOString();
}
// app.ts:
import { formatDate } from './utils/date';
// Bundler includes only formatDate, not all of utils
// Ambient module for untyped JS:
declare module 'legacy-lib' {
export function init(config: object): void;
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
26
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 9
Amazonbot 7
Ahrefs 2
Google 2
Unknown AI 2
Also referenced
How they use it
crawler 21
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Low
⚡ Quick Fix
Use ES module syntax (import/export) not namespace or module keywords — TypeScript namespaces are legacy; configure moduleResolution: NodeNext or bundler to match your build tool
📦 Applies To
typescript 2.0
web
cli
🔍 Detection Hints
Legacy namespace MyApp {} syntax; triple-slash references; module resolution errors from wrong moduleResolution setting
Auto-detectable:
✓ Yes
typescript
eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File