More about Modules in Typescript
typescript modules
1. Exporting Types
You can export types such as interfaces, type aliases, and enums in addition to functions, classes, and variables.
// types.ts
export interface Person {
name: string;
age: number;
}
export type ID = string | number;
// main.ts
import { Person, ID } from "./types";
const user: Person = { name: "Alice", age: 30 };
const userId: ID = 123;
console.log(user, userId);
2. Re-exports
You can re-export a module’s exports without explicitly importing them.
// math.ts
export const add = (a: number, b: number) => a + b;
export const subtract = (a: number, b: number) => a - b;
// operations.ts
export * from "./math";
// main.ts
import { add, subtract } from "./operations";
console.log(add(3, 2)); // Output: 5
console.log(subtract(5, 2)); // Output: 3
3. Import Aliases
You can use aliases to rename imports for better readability or to avoid conflicts.
// utils.ts
export const calculate = (a: number, b: number) => a + b;
// main.ts
import { calculate as add } from "./utils";
console.log(add(5, 3)); // Output: 8
4. Importing All Exports
You can import everything from a module as a single object.
// math.ts
export const add = (a: number, b: number) => a + b;
export const multiply = (a: number, b: number) => a * b;
// main.ts
import * as MathUtils from "./math";
console.log(MathUtils.add(2, 3)); // Output: 5
console.log(MathUtils.multiply(2, 3)); // Output: 6
5. Dynamic Imports
Dynamic imports allow you to load modules at runtime, which is useful for lazy-loading or conditional imports.
// file1.ts
export const greet = (name: string) => `Hello, ${name}`;
// main.ts
async function loadGreet() {
const { greet } = await import("./file1");
console.log(greet("Alice")); // Output: Hello, Alice
}
loadGreet();
6. Module Resolution
TypeScript uses a module resolution strategy to locate and import modules. The two strategies are:
Node.js (CommonJS) Resolution:
- Used by default when working in a Node.js environment.
- Looks for
.ts
,.tsx
,.js
, or.json
files in the specified path.
ES Module (ECMAScript) Resolution:
- Used for modern JavaScript projects with ES Modules.
- Requires setting
module
toESNext
orESModule
intsconfig.json
.
7. Configuring Modules in TypeScript
TypeScript’s module system is configured in the tsconfig.json
file. Important options include:
module
:
Specifies the output module format (e.g., CommonJS
, ESNext
, or AMD
).
{
"compilerOptions": {
"module": "CommonJS"
}
}
moduleResolution
:
Controls how modules are resolved. Can be set to node
or classic
.
{
"compilerOptions": {
"moduleResolution": "node"
}
}
baseUrl
and paths
:
Used to define aliases for module paths.
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@utils/*": ["src/utils/*"]
}
}
}
// main.ts
import { calculate } from "@utils/math";
8. Module Best Practices
- Use Named Exports for Multiple Items: Default exports can cause confusion in larger projects.
export const add = (a: number, b: number) => a + b; export const subtract = (a: number, b: number) => a - b;
-
Organize Files Logically: Group related files into folders and avoid long import paths by using aliases.
- Avoid Importing from Deep Paths:
// Bad import { something } from "../../utils/math"; // Good import { something } from "@utils/math";
- Prefer Type-Only Imports: Use
import type
for importing only types to reduce runtime overhead.import type { Person } from "./types";