Type Safety Tips
Following these practices will help you get the most out of TypeScript's type system.
- Avoid 'any' — use 'unknown' when the type is truly unknown
- Enable strict mode in tsconfig.json
- Use type inference — don't annotate when TypeScript can infer
- Prefer interfaces for object shapes, types for unions and utilities
- Use discriminated unions for complex state modeling
- Keep types close to where they're used
Common Patterns
These patterns appear frequently in well-typed TypeScript codebases.
Example
// 1. Use 'as const' for literal types
const CONFIG = {
apiUrl: "https://api.example.com",
timeout: 5000
} as const;
// 2. Use satisfies for type checking without widening
type Colors = Record<string, [number, number, number]>;
const palette = {
red: [255, 0, 0],
green: [0, 255, 0]
} satisfies Colors;
// palette.red is still [number, number, number], not Colors
// 3. Branded types for type-safe IDs
type UserId = number & { __brand: 'UserId' };
type OrderId = number & { __brand: 'OrderId' };
function getUser(id: UserId) { /* ... */ }
// getUser(123 as OrderId); // Error! Project Organization
Organize your TypeScript projects for maintainability and developer experience.
- Keep shared types in a dedicated types/ directory
- Use barrel exports (index.ts) for clean imports
- Co-locate component types with their components
- Use path aliases in tsconfig for cleaner imports
- Run tsc --noEmit in CI to catch type errors
- Use eslint with @typescript-eslint for additional checks
