Why TypeScript Shows “Cannot use namespace ‘X’ as a value” in import Statements

When working with TypeScript, you may encounter the error:

“Cannot use namespace ‘X’ as a value.”

This happens when you mistakenly treat a TypeScript namespace—or anything that exists only in the type space—as if it were a runtime value. It’s a common point of confusion, even for intermediate developers.

This article explains why the error occurs, the type/value distinction, and common import pitfalls that lead to this problem.

Why the Error Happens

TypeScript maintains a strict separation between:

  • Types (exist only at compile time)
  • Values (exist at runtime)

Namespaces belong to the type space, so they don’t exist as runtime objects. Therefore, the following code triggers the error:

Incorrect Example (Causes Error)

import * as MyTypes from './types';

const x = MyTypes; // ❌ Cannot use namespace 'MyTypes' as a value

MyTypes contains only type information; it is not an actual runtime variable.

Common Pitfalls

1. Attempting a default import for a type

import MyType from './types'; // ❌ Types cannot be default-imported
Correct:
import type { MyType } from './types';

2. Treating namespace imports as runtime objects

This often happens when developers group many types into a single file:

// types.ts
export type A = string;
export type B = number;

// main.ts
import * as MyTypes from './types';

const v = MyTypes.A; // ❌ Accessing as a runtime value
Correct:
import type { A, B } from './types';

3. Confusing namespaces with enums

Enums do exist at runtime, which leads to confusion:

import { MyEnum } from './enums';

const x = MyEnum.A; // ✅ This works because enums are runtime objects

Namespaces do not behave the same way.

How to Fix the Error

1. Use import type for type-only imports

import type { User, Config } from './types';

2. Export actual values if you need runtime objects

// config.ts
export const settings = {
  retry: 3
};
// main.ts
import { settings } from './config';
console.log(settings.retry); // OK

3. Keep types and values clearly separated

This eliminates most namespace-related issues.

Summary

  • Namespaces exist only in the type space, not as runtime values
  • import * as X from a type-only file results in namespace imports that can’t be used as values
  • Use import type when importing type definitions
  • Export real objects if you need something at runtime

Understanding the separation between TypeScript’s “type world” and “value world” helps prevent the “Cannot use namespace as a value” error entirely。

Copied title and URL