Modules and Imports
Modules and Imports
Section titled βModules and ImportsβWhat it means
Section titled βWhat it meansβTypeScript uses standard ES module syntax (import/export) to split code across files, and additionally supports type-only imports β importing just a type or interface with no runtime footprint, which the compiler strips out entirely during compilation.
Examples
Section titled βExamplesβexport function add(a: number, b: number): number { return a + b;}export interface Point { x: number; y: number; }export default class Calculator { /* ... */ }
// app.tsimport Calculator, { add, Point } from "./math";import type { Point } from "./math"; // type-only import -- erased at compile time
const p: Point = { x: 1, y: 2 };const sum = add(2, 3);
// Re-exporting from a barrel fileexport * from "./math";export { add as addNumbers } from "./math";Common mistake
Section titled βCommon mistakeβCreating a circular dependency between modules (A imports from B, B imports from A) β this often works for types (which are erased and donβt have a runtime execution order) but can fail unpredictably for values, since one module may not have finished initializing when the other tries to use it.
import { b } from "./b";export const a = b + 1; // may be `undefined + 1` = NaN if b.ts hasn't run yet
// b.tsimport { a } from "./a";export const b = a + 1; // circular! neither can safely initialize first
// Fix: extract the shared logic into a third module both can import from,// or use `import type` if you only actually need the type, not the valueQuick practice
Section titled βQuick practiceβ-
Whatβs the difference between
import { Point }andimport type { Point }?Answer
import typetells the compiler this import is used only for type checking and can be completely erased from the compiled output β it has zero runtime footprint. -
Why can circular imports be risky for values but usually safe for types?
Answer
Types are erased at compile time and have no execution order to worry about; values are real runtime code, so a circular import can mean one module tries to use a value from another before it's finished initializing. -
What does
export defaultlet a consuming module do differently from a named export?Answer
It can be imported without curly braces and under any name the importer chooses:import AnyNameYouWant from "./module", versus named exports which must match the exported name (or be explicitly aliased withas).