BeCuriouzLearn something new every day
import, export, and the type Keyword
💡 Use export/import to share values between ES modules, and import type for names used only as types so they're erased from the compiled JavaScript.
Modern TypeScript ships as ES modules (ESM): each file is its own scope, and you must explicitly export what others can use and import what you need. A named export exposes a symbol by name; a default export marks the one main thing a file provides:
// math.ts
export const PI = 3.14; // named export
export function area(r: number) { // named export
return PI * r * r;
}
export default class Circle {} // default export// app.ts
import Circle, { PI, area } from "./math";Named imports use curly braces and must match the exported name (rename with as: import { area as circleArea }). A default import needs no braces and you pick any name for it. Note the module specifier "./math" — the .ts extension is omitted, and the leading ./ marks it as a relative path rather than a package from node_modules.
TypeScript adds a twist: you can export and import types, not just values. Because types vanish at runtime, prefer import type for type-only imports. This tells the compiler (and bundlers) the import can be fully erased from the emitted JavaScript, avoiding accidental runtime dependencies or side effects:
// user.ts
export interface User { id: number; name: string; }
// app.ts
import type { User } from "./user"; // erased at compile time
import { area } from "./math"; // real runtime valueYou can also mark individual members inline: import { type User, area } from "...". The rule of thumb: use import type when a name is used only in type positions (annotations, generics), and a plain import when you actually call or evaluate it at runtime.