← 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.
Syntax
typescript
let value: SpecificType;                 // prefer a specific type over any

function identity<T>(input: T): T {      // or a generic
    return input;
}

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);
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Declaring a value as any to silence an error, so value.nonExistentMethod() compiles and crashes at runtime.
  2. Leaving parameters untyped, which implicitly become any unless noImplicitAny is on.
  3. Using any[] for arrays instead of a typed array or a generic, losing element type checks.
🔒

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.