Ch. 2 · TypeScript

TypeScript Type Imports and Runtime Modules

TypeScript Type Imports and Runtime Modules. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readadvancedupdated Oct 3, 2026

Type-only imports express dependencies needed for checking but absent at runtime. This helps clarify module boundaries and avoid accidental runtime imports.

Before you start

You should be comfortable with JavaScript values, functions and objects. Use a TypeScript project with strict checking enabled when trying the examples. Separate what the compiler proves from what must still be checked when values arrive at runtime.

The practical goal is to reason through this situation: Use import type for an interface consumed solely in annotations. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.

Step-by-step walkthrough

Step 1: Classify each imported use

An interface used in annotations is type-only. A constructor, function call or value passed to a decorator is evaluated at runtime.

Step 2: Use explicit type imports

Import annotation-only dependencies with import type. This documents that emitted JavaScript does not require those bindings.

Step 3: Retain needed runtime values

Do not convert a class import if code constructs it. Inspect emitted output and module behavior under the project’s module settings.

Worked scenario

Use import type for an interface consumed solely in annotations.

// contracts.ts
export interface User { id: string }
TypeScript
// consumer.ts
import type { User } from './contracts';
export function identity(user: User): string {
  return user.id;
}
TypeScript

These are two separate files. The interface and the type-only import are erased from emitted JavaScript; the exported identity function remains executable code.

Common mistake

A class used as a constructor or decorator value is still a runtime dependency.

Verify the behavior

Inspect emitted consumer JavaScript. Compare an interface import with a class used by new; converting the latter to type-only should make the runtime-value use fail checking.

Interview exercise

Why did converting an import break code?

Answer and reasoning

The code needed a runtime value. Distinguish type positions from actual evaluation before removing emitted imports.

Continue learning

Compare the scenario with the TypeScript interview questions and test your understanding with the TypeScript MCQs. For terminology and implementation details, consult the reference material.

More in TypeScript

read ✓TypeScript · hard

TypeScript Abstract Classes and Contracts

Share behavior with abstract classes, enforce required members, and decide when an interface or composition is the better contract.

~2 min readread →
read ✓TypeScript · mid

TypeScript Enums vs Union Types

Compare enums with unions of string literals: runtime cost, serialization, exhaustiveness and which one fits application code.

~3 min readread →
esc