Never use `any` as a type annotation. `any` disables all type checking for that value and everything it touches, spreading through your codebase like a virus — one `any` can silently disable type safety across dozens of files.
Why This Matters
A single `any` type doesn't just disable checking for one variable — it propagates. When you pass an `any` value to a function, the return type becomes `any`. When you assign `any` to a typed variable, no error is raised. Over time, `any` spreads through imports and function calls, silently disabling TypeScript's ability to catch bugs at compile time. Teams often discover this only after a production crash.
any is not a type — it is an escape hatch that disables TypeScript's entire type system for that value. The danger is that any is contagious:
const data: any = fetchData();const name = data.user.name; // no error — even if data has no user propertyprocessName(name); // name is now also any inside processName
One any at the boundary silently disables type checking for every function that touches the value. TypeScript won't warn you about misspelled properties, wrong argument types, or null access. You only discover the problem at runtime — usually in production.
Codebases with widespread any usage get the worst of both worlds: they pay the cost of TypeScript (compilation step, type annotations, .ts files) but receive none of the safety benefits.
The rule
Never use any. For every any in your code, there is a safer alternative:
If you don't know the type yet, use unknown and narrow it
If it can be multiple types, use a union type
If it's a generic container, use a type parameter
If it comes from an external API, define an interface for the response shape
Bad example
// BAD: any disables all type safetyfunction processApiResponse(response: any) { // No errors — TypeScript trusts you completely const users = response.data.users; // could be undefined return users.map((u: any) => u.naem); // typo not caught}// BAD: any in catch blockstry { await fetchData();} catch (error: any) { console.log(error.mesage); // typo not caught}
Good example
// GOOD: define the shapeinterface ApiResponse { data: { users: User[]; };}function processApiResponse(response: ApiResponse) { const users = response.data.users; // fully typed return users.map((u) => u.name); // typo would be caught}// GOOD: use unknown for catch blockstry { await fetchData();} catch (error: unknown) { if (error instanceof Error) { console.log(error.message); // type-safe access }}