TypeScript brings type safety to JavaScript, but using it effectively requires a few key habits. From strict mode and type narrowing to generics and avoiding common pitfalls, here are the practices that will make your codebase easier to maintain and refactor.
Turn on strict mode. It catches more errors at compile time and encourages better patterns. Start new projects with strict: true; for existing codebases, enable it gradually and fix issues file by file. The short-term pain pays off in fewer runtime bugs.
Prefer interfaces for object shapes and use type for unions, intersections, and mapped types. Keep types close to where they're used, and extract shared types into a dedicated file or module when they're reused. Avoid any—use unknown and narrow with type guards when you need flexibility.
Use generics to keep types flowing through functions and components. Well-typed APIs make refactoring safe: change a type in one place and the compiler surfaces every place that needs updating. Generic constraints help you express "this function works on any object with property X" without losing type information.
Don't over-engineer. Not everything needs a generic or a conditional type. If a type is getting hard to read or write, simplify. Sometimes a well-placed type assertion or a small any is pragmatic. Document why and keep the surface area small.
Key Takeaways
- Enable strict mode to catch more errors and encourage safer code.
- Use interfaces for objects and type for unions; avoid any, prefer unknown.
- Leverage generics so types flow through and refactors stay safe.
- Keep types simple; use assertions sparingly and only when justified.


