Namespaces
A namespace is TypeScript's older way of grouping related code under one named object so it doesn't leak into the global scope, compiling down to a simple immediately-invoked function that exposes only its exported members.
Learn Namespaces in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
A namespace is like a labelled drawer in a filing cabinet. Everything related to "Geometry" goes in the Geometry drawer, so its names never collide with the "Banking" drawer next to it. The drawer also has a private back compartment (un-exported helpers) that only the drawer's own contents can reach. ES modules are the modern upgrade: instead of one big cabinet, each file is its own drawer with its own lock.
1. Declaring a Namespace & the Compiled IIFE
You declare a namespace with namespace Name {' '} and mark the parts you want visible with export . The compiler turns this into an IIFE that creates one object and bolts the exported members onto it. Anything you don't export becomes a private function trapped inside the closure — which is exactly how the namespace keeps helpers hidden.
2. Nested Namespaces
Namespaces can nest , producing a dotted path like App.Models.User . At runtime that's just nested objects: App has a Models property which has the user helpers. When the path gets long, an import Alias = App.Models shorthand keeps your code readable.
3. Namespaces vs ES Modules (Prefer Modules)
Today, ES modules are the right default. A module is a file that uses import / export ; each file has its own scope, and bundlers can tree-shake away unused exports. Namespaces predate modules and put everything on one global object. Reserve namespaces for global declaration files ( .d.ts ) where modules aren't available.
🎯 Your Turn
Hand-compile a MathUtils namespace with two exported helpers. Fill in the two blanks marked ___ , then run it.
No blanks this time — just a brief and a starting outline. Build the IIFE yourself, run it, and check your output against the example in the comments.
Practice quiz
What is a TypeScript namespace?
- A runtime database
- A type of variable
- A way to group related code under one named object
- A CSS scope
Answer: A way to group related code under one named object. A namespace groups related code under a single named object so it does not pollute the global scope.
What does a namespace compile to?
- An IIFE that builds one object and attaches exported members
- A class
- A separate file
- Nothing at all
Answer: An IIFE that builds one object and attaches exported members. A namespace compiles to an immediately-invoked function expression that builds one object.
Why is only an exported member visible outside the namespace?
- Exported members run first
- Non-exported members are deleted
- It is random
- The compiled IIFE only attaches exported members to the object
Answer: The compiled IIFE only attaches exported members to the object. Un-exported members stay private inside the IIFE's closure; export moves them to the public object.
What does nesting namespaces produce, like App.Models.User?
- A single flat object
- Nested objects: App has a Models property holding the helpers
- An array
- A union type
Answer: Nested objects: App has a Models property holding the helpers. Nested namespaces compile to nested objects forming a dotted access path.
Which should you prefer for modern application code?
- ES modules (import/export)
- Namespaces
- Global variables
- Script tags only
Answer: ES modules (import/export). ES modules give each file its own scope and work with bundlers and tree-shaking.
Where do namespaces still legitimately appear?
- In every React component
- In package.json
- In global declaration (.d.ts) files
- In CSS files
Answer: In global declaration (.d.ts) files. Namespaces are still used in global .d.ts files, e.g. declare namespace NodeJS { ... }.
How do you shorten a long namespace path?
- With export default
- With an import alias like import Models = App.Models
- By deleting levels
- With typeof
Answer: With an import alias like import Models = App.Models. import Alias = App.Models creates a shorthand for a deep namespace path.
If a file already has top-level import/export, do you usually need a namespace?
- Yes, always
- Only with classes
- Only in strict mode
- No, the file is already a module with its own scope
Answer: No, the file is already a module with its own scope. A file with import/export is already a module, so you almost never need a namespace inside it.
What happens to a namespace member declared without export?
- It becomes a global
- It stays private inside the closure, invisible outside
- It is exported automatically
- It throws an error
Answer: It stays private inside the closure, invisible outside. Without export it is a private function or variable trapped inside the IIFE.
A namespace can merge with which of these of the same name?
- A string literal
- An import statement
- A class or function
- A number
Answer: A class or function. A namespace merges with a class or function of the same name to add nested types or static helpers.