TypeScript Configuration & Best Practices
tsconfig.json Essentials
{
"compilerOptions": {
// Language version
"target": "ES2022",
"lib": ["ES2022", "DOM"],
// Module system
"module": "ESNext",
"moduleResolution": "bundler",
// Strict type checking (recommended)
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
// Additional checks
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
// Emit
"declaration": true,
"sourceMap": true,
"outDir": "./dist",
// Interop
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
// Advanced
"skipLibCheck": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}Best Practices
1. Always Enable Strict Mode
// ❌ BAD: Without strict mode
function greet(name) { // any type
return name.toUpperCase();
}
greet(null); // Runtime error!
// ✅ GOOD: With strict mode
function greet(name: string): string {
return name.toUpperCase();
}
// greet(null); // ✅ Compile error!2. Avoid using any
// ❌ BAD
function process(data: any): any {
return data.value;
}
// ✅ GOOD: Use unknown for true unknowns
function process(data: unknown): string {
if (typeof data === 'object' && data !== null && 'value' in data) {
return String((data as any).value);
}
throw new Error('Invalid data');
}
// ✅ BETTER: Use generics
function process<T extends { value: string }>(data: T): string {
return data.value;
}3. Use Type Inference
// ❌ Redundant
const name: string = 'John';
const age: number = 30;
// ✅ GOOD: Let TypeScript infer
const name = 'John'; // Inferred as string
const age = 30; // Inferred as number
// ✅ Do annotate function returns (for clarity)
function getUser(): User {
return { id: 1, name: 'John' };
}4. Prefer Interfaces for Objects
// ✅ GOOD: Interface for objects
interface User {
id: number;
name: string;
}
interface Admin extends User {
role: string;
}
// Use type for unions, primitives, tuples
type ID = string | number;
type Point = [number, number];5. Use Const Assertions
// Without const assertion
const colors = ['red', 'green', 'blue']; // Type: string[]
// ✅ With const assertion
const colors = ['red', 'green', 'blue'] as const;
// Type: readonly ['red', 'green', 'blue']
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000
} as const;
// All properties become readonly
// Use for exact literal types
type Color = typeof colors[number]; // 'red' | 'green' | 'blue'Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free