Namespaces

What Is a Namespace in TypeScript?

In TypeScript a namespace is an encapsulation of identifiers dedicated to the semantic separation of those identifiers from the global scope.

TypeScript namespaces are sometimes referred to as internal modules.

Namespaces (with the exclusion of ambient namespaces) are a TypeScript runtime extension to JavaScript and they compile to JavaScript objects enclosed within IIFEs (immediately invoked function expressions).

// TypeScript
namespace Foo {
  export const bar = 42
}
// Compiled JavaScript
"use strict";
var Foo;
(function (Foo) {
    Foo.bar = 42;
})(Foo || (Foo = {}));

Accessing Namespace Identifiers

Identifiers prefixed with the export keyword within a namespace can be accessed from outside the namespace but those not prefixed cannot.

The exported namespace identifiers can be accessed using the dot notation.

While accessing an exported namespace identifier it is allowed but not required to use the import keyword which is called aliasing.

// TypeScript
namespace Foo {
  export const bar = 42
  export const baz = '42'
  const qux = 'forty two'
}

const bar = Foo.bar
console.log(bar) // 42
import baz = Foo.baz
console.log(baz) // '42'
const qux = Foo.qux // TS: Property 'qux' does not exist on type 'typeof Foo'.
console.log(qux) // undefined
// Compiled JavaScript
"use strict";
var Foo;
(function (Foo) {
    Foo.bar = 42;
    Foo.baz = '42';
    const qux = 'forty two';
})(Foo || (Foo = {}));
const bar = Foo.bar;
console.log(bar);
var baz = Foo.baz;
console.log(baz);
const qux = Foo.qux;
console.log(qux);

Namespace Declaration Merging

Similarly to interfaces, multiple namespace declarations are merged.

// TypeScript
namespace Foo {
  export const baz = 42
}

namespace Foo {
  export const bar = '42'
}

console.log(Foo) // {baz: 42, bar: '42'}
// Compiled JavaScript
"use strict";
var Foo;
(function (Foo) {
    Foo.baz = 42;
})(Foo || (Foo = {}));
(function (Foo) {
    Foo.bar = '42';
})(Foo || (Foo = {}));
console.log(Foo);

Ambient Namespaces

To describe existing JavaScript modules or objects it is possible to use the so-called ambient namespaces i.e. namespaces encapsulating types only.

// TypeScript
declare namespace Foo {
  export interface Baz {
    bar: string
  }
}
// Compiled JavaScript
"use strict"

As presented above ambient namespaces are not compiled to JavaScript.

Namespaces can also merge with declared classes, functions, and enums.