← Back to TypeScript Course | Chapter 23: Performance and Best Practices | Lesson 1 of 7

Avoiding any

The any type turns off much of TypeScript's type checking. Avoiding any keeps errors visible and encourages safer alternatives such as generics, unknown, specific object types, and union types.

Why any Is Risky

A value typed as any can be passed around, called, and accessed almost anywhere with zero compiler checks — this can silently hide exactly the mistakes TypeScript exists to catch before the program ever runs.

Example: Why any Is Risky

typescript
let value: any = "hello";
value = value.nonExistentMethod(); // compiles, but crashes at runtime
console.log("any bypasses all compiler checks");

Use Specific Types

When the expected shape of a value is actually known, write that shape out directly as a type — specific types give real autocomplete and immediately catch invalid assignments or missing properties that any would let through unnoticed.

Example: Use Specific Types

typescript
interface User {
  name: string;
  age: number;
}
function greet(user: User) {
  return `Hello, ${user.name}`;
}
console.log(greet({ name: "Ravi", age: 25 }));

Use Generics Instead of any

Generics preserve the relationship between a function's input and output types across many different concrete types, which is usually a better fit than any for reusable functions that need to work generically.

Example: Use Generics Instead of any

typescript
function identity<T>(value: T): T {
  return value;
}
console.log(identity(42), identity("hello"));

Use Unknown for Untrusted Data

unknown is a much safer choice than any for values whose type genuinely isn't known ahead of time, because it forces the program to narrow the value with a real check before it can be used for anything.

Example: Use Unknown for Untrusted Data

typescript
function process(value: unknown) {
  if (typeof value === "string") {
    console.log(value.toUpperCase());
  }
}
process("hello");

Use Explicit Escape Hatches Carefully

Sometimes a library integration or a migration genuinely requires a type assertion as an escape hatch — keep those assertions narrow and local rather than reaching for any across an entire codebase as a shortcut.

Example: Use Explicit Escape Hatches Carefully

typescript
interface LegacyApi {
  oldMethod(): string;
}
const legacy = {} as LegacyApi; // narrow, local, documented escape hatch
console.log(typeof legacy.oldMethod);
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.