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.