TypeScript Best Practices
TypeScript's value comes almost entirely from how precisely and honestly your types describe your actual data — a codebase full of any and loose type assertions gets very little of TypeScript's real benefit while paying its full complexity cost.
Last updated 2026-09-08
Avoid any — use unknown when a type genuinely isn't known yet
any disables type checking entirely for that value, silently propagating through anything it touches. unknown forces an explicit type check or assertion before use, preserving safety while still allowing genuinely-unknown data.
Enable strict mode in tsconfig
Strict mode turns on a cluster of meaningfully useful checks (null checks, implicit any detection, and more) that catch real bugs. A non-strict TypeScript project gets a fraction of the language's actual safety benefit.
Prefer interfaces or type aliases over inline object types for anything reused
A shape used in more than one place should be named and defined once, not duplicated inline — this keeps related types in sync and makes refactoring safer.
Use type inference where it's clear, explicit annotations where it isn't
Annotating every single variable explicitly, even when TypeScript can infer it perfectly from context, adds noise without adding safety. Reserve explicit annotations for function signatures, exported values, and places where inference genuinely can't determine the intended type.
Avoid type assertions (as) as a way to silence errors you don't understand
A type assertion tells the compiler 'trust me,' overriding its own checking — using it to make an error message go away without understanding why it appeared just moves a potential bug from compile-time to runtime.
Common Mistakes to Avoid
- ⚠Sprinkling any everywhere to silence errors instead of properly typing the actual shape
- ⚠Non-strict tsconfig, missing out on most of TypeScript's real safety benefit
- ⚠Type assertions (as SomeType) used to bypass an error rather than fix the underlying type mismatch
- ⚠Duplicating the same object shape inline in multiple places instead of a shared named type
- ⚠Ignoring TypeScript errors with @ts-ignore instead of addressing the actual type issue
Frequently Asked Questions
What's the real difference between any and unknown?
any disables all type checking on that value — you can call any method or access any property with no compiler complaint. unknown requires you to narrow the type (via a check or assertion) before doing anything with the value, which is far safer while still handling genuinely unknown data.
Should I use interface or type for object shapes?
Both work for most everyday cases; interface supports declaration merging and is often preferred for public API shapes, while type is more flexible for unions and complex compositions. Team consistency matters more than which one you pick.