Modules and Namespaces
Importing/Exporting types, difference between value and type imports, and declaration files.
🧑🏫 Sabse pehle — simple mein samjho#
TypeScript aur JavaScript dono modules (file to file imports/exports) same tareeqe se use karte hain (import / export). Farak sirf itna hai ki TS mein hum values/variables ke alawa Types (Interfaces/Type aliases) ko bhi export aur import karte hain.
Importing and Exporting Types#
Works exactly like standard JS modules:
user.types.ts (Exporting)
export interface User {
id: number;
name: string;
}
export type Status = "success" | "error";
app.ts (Importing)
import { User, Status } from "./user.types";
let loggedInUser: User = { id: 1, name: "Tarun" };
import type (The Best Practice ✨)#
Modern TypeScript (and bundlers like Vite/Webpack) prefer that you explicitly clarify what you are importing: a Value (JS code) or a Type. Types are completely erased after compilation. Explicitly defining them helps the bundler clean up files much more efficiently.
import type { User } from "./user.types"; // The entire module import is strictly for types
// OR Inline type imports:
import { someFunction, type Status } from "./user.types";
Global Types (Ambient Declarations)#
Sometimes you want an interface like User to be available in every file without writing an import statement. Just like Window or Document are globally available by default.
To achieve this, we use .d.ts (Declaration files).
Create a types/global.d.ts file:
// Do not use the export keyword inside this file; only then will TS treat it as "global"
interface GlobalUser {
id: number;
email: string;
}
Now, as long as the TS compiler reads this .d.ts file, the GlobalUser type will be accessible throughout the entire project without any imports!
3rd Party Libraries and @types#
When we install a legacy JavaScript library from npm (like lodash or express), they do not contain TS types natively. TypeScript gets frustrated: "Could not find a declaration file for module".
The community (DefinitelyTyped) created a fix for this. You can install their type definitions separately.
npm install express
npm install -D @types/express # This provides the missing Types for the library
Nowadays, many modern libraries (like Axios, React) are written natively in TypeScript, meaning their types are built-in and do not need to be installed separately.
Namespaces (The Legacy Approach)#
Before ES6 Modules became the standard, TS used namespace to organize classes/interfaces inside files. Nowadays, its usage has plummeted (almost non-existent in React/Node apps), but you might still spot it in legacy code.
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
}
// Usage outside the namespace:
let myValidator: Validation.StringValidator;
Today, we simply handle this by relying on direct export statements and a solid folder/file structure.