top Any-ing Around: 12 TypeScript Best Practices You’ll Thank Me For

Stop Any-ing Around: 12 TypeScript Best Practices You’ll Thank Me For

Let’s face it — we’ve all been there. Staring at a red squiggly line in our IDE, whispering “just this once,” and slapping an any on a variable like duct tape on a leaky pipe.

But TypeScript deserves better. You deserve better. So buckle up, because I’m about to share 12 TypeScript best practices that will make your code cleaner, safer, and dare I say… elegant?


1. ❌ Avoid any Like It’s on Fire

If you use any, you’re just writing JavaScript with extra steps. – Probably someone wise

Instead of:

function processData(data: any) {
  console.log(data.name);
}

Use:

function processData(data: { name: string }) {
  console.log(data.name);
}

🧠 Tip: If you must use something flexible, try unknown or generics instead of any.

2. ✅ Prefer type or interface, But Be Consistent

Both are valid! Use interface for object shapes you expect to extend, and type for unions or function signatures.

interface User {
  name: string;
  age: number;
}

type ResponseStatus = 'success' | 'error';

🚨 Mixing them randomly? That’s the TypeScript equivalent of putting ketchup on spaghetti.

3. 💡 Use Type Inference, but Don’t Over-rely

TypeScript is smart. Let it infer when it can, but explicit is better than implicit for exported values and public APIs.

const name = 'Alice'; // okay to infer
export const MAX_RETRIES: number = 5; // better to be explicit

4. 🛑 Never Ignore the Compiler

You know that red error? It’s not a suggestion, it’s a cry for help.

Fix. Your. Types.

5. 📦 Use Readonly, Partial, Pick, and Record

These utility types are like magical Lego bricks.

type ReadonlyUser = Readonly<User>;
type PartialUser = Partial<User>;
type NameOnly = Pick<User, 'name'>;
type Roles = Record<string, 'admin' | 'user'>;

They make your life easier — embrace them.

6. 🧱 Model Your Data Precisely

Don’t be lazy with types. Use literal types, enums, and unions to model the real world.

type OrderStatus = ‘pending’ | ‘shipped’ | ‘cancelled’;

Or, if you’re fancy:

enum OrderStatus {
  Pending = 'pending',
  Shipped = 'shipped',
  Cancelled = 'cancelled'
}

7. 🤹‍♂️ Go Generic — But With Purpose

Generics = flexible but typesafe.

function wrapInArray<T>(value: T): T[] {
  return [value];
}

Don’t use <T> because it looks cool. Use it when your function should work with multiple types.

8. 🔍 Use strict Mode (Seriously)

Enable this in your tsconfig.json:

{
  "compilerOptions": {
    "strict": true
  }
}

This is not optional. This is TypeScript on beast mode. You’ll catch bugs before they hatch.

9. 🪓 Narrow Your Types — Guard Them Well

Type guards are your best friends.

function isUser(obj: any): obj is User {
  return obj && typeof obj.name === 'string';
}

The more you narrow a type, the less likely it is to blow up in production.

10. 📚 Document Your Types Like an Adult

Types can be self-documenting. But still — use JSDoc or comments when things get gnarly.

/**
 * Represents a user's order history.
 */
type OrderHistory = Order[];

11. 📦 Split Types Into Modules

If your types.ts file is 900 lines long, it’s time for a refactor. Group types by domain or feature for sanity’s sake.

12. 🧪 Don’t Forget to Test Your Types (Yes, Really)

Tools like tsd let you write assertion tests for your type definitions.
Because you shouldn’t ship types you haven’t tested — just like you wouldn’t ship code you haven’t tested. (Right?)

🧠 Final Thoughts

TypeScript isn’t just JavaScript with types — it’s a way to design better code.
And once you get the hang of it, it’s like coding with a safety net… made of lasers.

So go forth, type with confidence, and please — stop any-ing around.

Article Writter By

Long Phạm

"Thành công nuôi dưỡng sự hoàn hảo. Sự hoàn hảo lại nuôi lớn thất bại. Chỉ có trí tưởng tượng mới tồn tại."