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.
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.
BeforeMerge scans your pull requests against this rule and 3+ others. Get actionable feedback before code ships.
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 property
processName(name); // name is now also any inside processNameOne 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.
Never use any. For every any in your code, there is a safer alternative:
unknown and narrow it// BAD: any disables all type safety
function 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 blocks
try {
await fetchData();
} catch (error: any) {
console.log(error.mesage); // typo not caught
}// GOOD: define the shape
interface 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 blocks
try {
await fetchData();
} catch (error: unknown) {
if (error instanceof Error) {
console.log(error.message); // type-safe access
}
}Search for explicit any annotations:
grep -n ": any" --include="*.ts" --include="*.tsx" -r src/
grep -n "as any" --include="*.ts" --include="*.tsx" -r src/Use the @typescript-eslint/no-explicit-any rule to enforce this automatically:
{
"rules": {
"@typescript-eslint/no-explicit-any": "error"
}
}@typescript-eslint/no-explicit-any as an errorany parameters with proper interfaces or unknownany return types with explicit return typesas any casts with proper type narrowing@types/* packages or write declaration files